Index: libcxx/docs/DesignDocs/MultipleCharEncodings.rst =================================================================== --- /dev/null +++ libcxx/docs/DesignDocs/MultipleCharEncodings.rst @@ -0,0 +1,101 @@ + +============================ +Multiple Character Encodings +============================ + +Rationale +------------------------------------------ +Some platforms, such as z/OS, support multiple character encodings. In turn, the runtime needs to provide +several versions of the library as well. For example, z/OS needs an EBCDIC and ASCII version for character +encoding sensitive (CES) instances. + +Approach +------------------------------------------ + +Injecting inline namespaces for CES instances. Each encoding will have a seperate inline namespace. +For example, when an ordinary function calls a function in the CES namespace it splits off into the appropriate encoding path +(such as ASCII or EBCDIC). To achieve this, we define the :code:`_LIBCPP_BEGIN_NAMESPACE_CES` and :code:`_LIBCPP_END_NAMESPACE_CES` macros in `libcxx/include/__config` to wrap CES +members of the enclosing namespace. Note, the definition of these macros are conditional on the character mode set at compile time (for example the :code:`-fzos-le-char-mode=ascii` Clang option on z/OS). However, they are defined empty for non-CES platforms. + +************ +Implications +************ + +To allow for multiple versions of the library to be shipped as one, we need to build the library as many times as +the number of encodings (with appropriate options set for each build) and combine the symbols. For z/OS, this will be twice (once for EBCDIC and another for ASCII). +In particular, only CES source files (i.e. files that have CES code), need to be compiled more than once. For example, on z/OS there is a list (:code:`LIBCXX_CHARS_SENSITIVE_SOURCES` +in `libcxx/src/CMakeLists.txt`) that maintains the CES source files. In other words, the libc++ library is compiled in EBCDIC encoding and a few files (:code:`LIBCXX_CHARS_SENSITIVE_SOURCES`) are +compiled in the alternative (ASCII) encoding as well. + + +Nonetheless, CES source files and headers may have symbols that are outside the CES namespace. When building more than once, this may lead to +duplicate symbols. To avoid this, the :code:`_LIBCPP_ADDITIONAL_CHAR_ENCODING` macro is defined for the additional encodings to prevent duplication of exported symbols. With regards to z/OS, the primary encoding is EBCDIC and the additional char encoding is ASCII (fixed in *libcxx/include/__config*). +For example, :code:`__throw_runtime_error` in *libcxx/src/locale.cpp* is wrapped as follows to avoid compiling more than once. + +.. code-block:: c++ + + #if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + void __throw_runtime_error(const char* msg) + { + ... + } + #endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + +It should be noted that injecting a namespace will alter the symbol names exported from the library. As a result, recompilation of programs may be required. + +************************************************ +What is considered character encoding sensitive? +************************************************ +Exported classes and functions that deal with character and string literals and such functionality are subject to being CES. In general, examining the signature should help determine if an instance +should be in the CES namespace: + +- Functions with :code:`[w]char *` in their signature (i.e. arguments and/or return type). +- String conversion functions such as :code:`to_string(int __val)`. +- The :code:`char_traits` class. This allows us to avoid having unnecessary classes in the CES namespace. In particular, this class is used to handle most of the encoding, + since many CES instances are instantiated with the :code:`char_traits` class. For example, :code:`basic_string` is already a template instantiated with multiple + character types (see demangled symbol above). + + Nontheless, classes/functions only need the CES namespace added if they have encoding + sensitive features and *don't* have :code:`char_traits` as a template parameter. +- The :code:`ios_base` class. This is needed to handle CES I/O. + +It should be noted that this is not an exhaustive list. + +Exception classes should **not** be in the CES namespaces, otherwise the throw may not be caught at the right place. + +******************************************** +How to add an instance to the CES namespace? +******************************************** + +Simply put, we need to wrap the declaration and definition with :code:`_LIBCPP_BEGIN_NAMESPACE_CES` and :code:`_LIBCPP_END_NAMESPACE_CES`. For example, +here is how :code:`char_traits` class was added to the CES namespace: + +.. code-block:: c++ + + _LIBCPP_BEGIN_NAMESPACE_CES + + // char_traits + template + struct _LIBCPP_TEMPLATE_VIS char_traits { + ... + } + + _LIBCPP_END_NAMESPACE_CES + +Note that there might be more dependencies so other instances may need to be added to the CES namespace as well. + +********************* +Enabling bimodal mode +********************* + +There are some instances that we must select the correct encoding during the **execution** of a program. For example, :code:`__future_error_category::message(int)` (`libcxx/src/future.cpp`) should be returned +in EBCDIC or ASCII depending on the execution environment. Hence, we have an approach to have both (EBCDIC & ASCII) encodings in RTTI (Runtime Type Information). In particular, we replace string literals with +passing an enum to a macro. + +For example, code like: + +:code:`return string("The associated promise has been destructed prior to the associated state becoming ready.");` + +will be replaced with: + +:code:`return string(getMessage(_BROKEN_PROMISE));` Index: libcxx/include/__config =================================================================== --- libcxx/include/__config +++ libcxx/include/__config @@ -227,6 +227,25 @@ # endif // defined(__GLIBC_PREREQ) #endif // defined(__linux__) +// CES stands for CHAR_ENCODING_SENSITIVE +#if defined(__MVS__) +#include // for __NATIVE_ASCII_F +#ifdef __NATIVE_ASCII_F + #define _LIBCPP_ADDITIONAL_CHAR_ENCODING + #define _LIBCPP_CES_NAMESPACE _ASCII:: + #define _LIBCPP_BEGIN_NAMESPACE_CES inline namespace _ASCII { + #define _LIBCPP_END_NAMESPACE_CES } +#else + #define _LIBCPP_CES_NAMESPACE _EBCDIC:: + #define _LIBCPP_BEGIN_NAMESPACE_CES inline namespace _EBCDIC { + #define _LIBCPP_END_NAMESPACE_CES } +#endif // __NATIVE_ASCII_F +#else +#define _LIBCPP_CES_NAMESPACE +#define _LIBCPP_BEGIN_NAMESPACE_CES +#define _LIBCPP_END_NAMESPACE_CES +#endif // defined(__MVS__) + #ifdef __LITTLE_ENDIAN__ # if __LITTLE_ENDIAN__ # define _LIBCPP_LITTLE_ENDIAN @@ -1150,8 +1169,8 @@ #endif #if defined(__BIONIC__) || defined(__NuttX__) || \ - defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \ - defined(__MVS__) || defined(__OpenBSD__) + defined(__Fuchsia__) || defined(__wasi__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE #endif Index: libcxx/include/__iterator/ostreambuf_iterator.h =================================================================== --- libcxx/include/__iterator/ostreambuf_iterator.h +++ libcxx/include/__iterator/ostreambuf_iterator.h @@ -21,6 +21,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES +template +_LIBCPP_HIDDEN +ostreambuf_iterator<_Ch, _Tr> +__pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, + const _Ch* __ob, const _Ch* __op, const _Ch* __oe, + ios_base& __iob, _Ch __fl); +_LIBCPP_END_NAMESPACE_CES + _LIBCPP_SUPPRESS_DEPRECATED_PUSH template class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator @@ -66,7 +75,7 @@ friend _LIBCPP_HIDDEN ostreambuf_iterator<_Ch, _Tr> - __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, + _LIBCPP_CES_NAMESPACE __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, const _Ch* __ob, const _Ch* __op, const _Ch* __oe, ios_base& __iob, _Ch __fl); }; Index: libcxx/include/__locale =================================================================== --- libcxx/include/__locale +++ libcxx/include/__locale @@ -50,6 +50,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES #if !defined(_LIBCPP_LOCALE__L_EXTENSIONS) struct __libcpp_locale_guard { @@ -509,6 +510,33 @@ # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT +#elif defined(__MVS__) +#if defined(__NATIVE_ASCII_F) + typedef unsigned int mask; + static const mask space = _ISSPACE_A; + static const mask print = _ISPRINT_A; + static const mask cntrl = _ISCNTRL_A; + static const mask upper = _ISUPPER_A; + static const mask lower = _ISLOWER_A; + static const mask alpha = _ISALPHA_A; + static const mask digit = _ISDIGIT_A; + static const mask punct = _ISPUNCT_A; + static const mask xdigit = _ISXDIGIT_A; + static const mask blank = _ISBLANK_A; +#else + typedef unsigned short mask; + static const mask space = __ISSPACE; + static const mask print = __ISPRINT; + static const mask cntrl = __ISCNTRL; + static const mask upper = __ISUPPER; + static const mask lower = __ISLOWER; + static const mask alpha = __ISALPHA; + static const mask digit = __ISDIGIT; + static const mask punct = __ISPUNCT; + static const mask xdigit = __ISXDIGIT; + static const mask blank = __ISBLANK; +#endif + static const mask __regex_word = 0x8000; #else # error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE? #endif @@ -732,6 +760,10 @@ static const short* __classic_upper_table() _NOEXCEPT; static const short* __classic_lower_table() _NOEXCEPT; #endif +#if defined(__MVS__) + static const unsigned short* __classic_upper_table() _NOEXCEPT; + static const unsigned short* __classic_lower_table() _NOEXCEPT; +#endif protected: ~ctype(); @@ -1768,6 +1800,7 @@ }; #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___LOCALE Index: libcxx/include/__string =================================================================== --- libcxx/include/__string +++ libcxx/include/__string @@ -158,7 +158,7 @@ _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \ _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) - +_LIBCPP_BEGIN_NAMESPACE_CES // char_traits template @@ -1155,6 +1155,7 @@ // This would be a nice place for a string_ref }; +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS Index: libcxx/include/__support/ibm/locale_mgmt_zos.h =================================================================== --- libcxx/include/__support/ibm/locale_mgmt_zos.h +++ libcxx/include/__support/ibm/locale_mgmt_zos.h @@ -14,10 +14,6 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - #define _LC_MAX LC_MESSAGES /* highest real category */ #define _NCAT (_LC_MAX + 1) /* maximum + 1 */ @@ -40,14 +36,16 @@ std::string lc_messages; } * locale_t; +_LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES // z/OS does not have newlocale, freelocale and uselocale. // The functions below are workarounds in single thread mode. -locale_t newlocale(int category_mask, const char* locale, locale_t base); -void freelocale(locale_t locobj); -locale_t uselocale(locale_t newloc); +_LIBCPP_FUNC_VIS locale_t newlocale(int category_mask, const char* locale, locale_t base); +_LIBCPP_FUNC_VIS void freelocale(locale_t locobj); +_LIBCPP_FUNC_VIS locale_t uselocale(locale_t newloc); + +_LIBCPP_END_NAMESPACE_CES +_LIBCPP_END_NAMESPACE_STD -#ifdef __cplusplus -} -#endif #endif // defined(__MVS__) #endif // _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_ZOS_H Index: libcxx/include/__support/ibm/xlocale.h =================================================================== --- libcxx/include/__support/ibm/xlocale.h +++ libcxx/include/__support/ibm/xlocale.h @@ -30,17 +30,17 @@ struct __setAndRestore { explicit __setAndRestore(locale_t locale) { if (locale == (locale_t)0) { - __cloc = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0); - __stored = uselocale(__cloc); + __cloc = std::newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0); + __stored = std::uselocale(__cloc); } else { - __stored = uselocale(locale); + __stored = std::uselocale(locale); } } ~__setAndRestore() { - uselocale(__stored); + std::uselocale(__stored); if (__cloc) - freelocale(__cloc); + std::freelocale(__cloc); } private: Index: libcxx/include/charconv =================================================================== --- libcxx/include/charconv +++ libcxx/include/charconv @@ -97,6 +97,7 @@ #include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES namespace __itoa { _LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer) _NOEXCEPT; @@ -596,6 +597,7 @@ #endif // _LIBCPP_CXX03_LANG +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS Index: libcxx/include/codecvt =================================================================== --- libcxx/include/codecvt +++ libcxx/include/codecvt @@ -62,6 +62,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES enum codecvt_mode { @@ -574,6 +575,7 @@ ~codecvt_utf8_utf16() {} }; +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_CODECVT Index: libcxx/include/filesystem =================================================================== --- libcxx/include/filesystem +++ libcxx/include/filesystem @@ -540,7 +540,9 @@ perms __prms_; }; +_LIBCPP_BEGIN_NAMESPACE_CES class _LIBCPP_TYPE_VIS directory_entry; +_LIBCPP_END_NAMESPACE_CES template struct __can_convert_char { @@ -905,6 +907,7 @@ }; #endif /* !_LIBCPP_HAS_NO_CHAR8_T */ #endif /* _LIBCPP_WIN32API */ +_LIBCPP_BEGIN_NAMESPACE_CES class _LIBCPP_TYPE_VIS path { template @@ -1512,6 +1515,8 @@ string_type __pn_; }; +_LIBCPP_END_NAMESPACE_CES + inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } @@ -1585,6 +1590,7 @@ #endif } +_LIBCPP_BEGIN_NAMESPACE_CES class _LIBCPP_TYPE_VIS path::iterator { public: enum _ParserState : unsigned char { @@ -1683,6 +1689,8 @@ return !(__lhs == __rhs); } +_LIBCPP_END_NAMESPACE_CES + // TODO(ldionne): We need to pop the pragma and push it again after // filesystem_error to work around PR41078. _LIBCPP_AVAILABILITY_FILESYSTEM_POP @@ -1754,6 +1762,7 @@ #endif // operational functions +_LIBCPP_BEGIN_NAMESPACE_CES _LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); @@ -1825,6 +1834,7 @@ path __temp_directory_path(error_code* __ec = nullptr); _LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_END_NAMESPACE_CES inline _LIBCPP_INLINE_VISIBILITY path current_path() { return __current_path(); @@ -2312,6 +2322,7 @@ return __weakly_canonical(__p, &__ec); } +_LIBCPP_BEGIN_NAMESPACE_CES class directory_iterator; class recursive_directory_iterator; class _LIBCPP_HIDDEN __dir_stream; @@ -3004,6 +3015,7 @@ end(const recursive_directory_iterator&) noexcept { return recursive_directory_iterator(); } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_AVAILABILITY_FILESYSTEM_POP Index: libcxx/include/ios =================================================================== --- libcxx/include/ios +++ libcxx/include/ios @@ -224,6 +224,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES typedef ptrdiff_t streamsize; @@ -393,6 +394,10 @@ size_t __parray_cap_; }; +_LIBCPP_FUNC_VIS +const error_category& iostream_category() _NOEXCEPT; +_LIBCPP_END_NAMESPACE_CES + //enum class io_errc _LIBCPP_DECLARE_STRONG_ENUM(io_errc) { @@ -408,9 +413,6 @@ struct _LIBCPP_TEMPLATE_VIS is_error_code_enum : public true_type { }; #endif -_LIBCPP_FUNC_VIS -const error_category& iostream_category() _NOEXCEPT; - inline _LIBCPP_INLINE_VISIBILITY error_code make_error_code(io_errc __e) _NOEXCEPT @@ -425,6 +427,8 @@ return error_condition(static_cast(__e), iostream_category()); } +_LIBCPP_BEGIN_NAMESPACE_CES + class _LIBCPP_EXCEPTION_ABI ios_base::failure : public system_error { @@ -591,6 +595,8 @@ clear(__rdstate_); } +_LIBCPP_END_NAMESPACE_CES + template class _LIBCPP_TEMPLATE_VIS basic_ios : public ios_base Index: libcxx/include/iosfwd =================================================================== --- libcxx/include/iosfwd +++ libcxx/include/iosfwd @@ -102,6 +102,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES class _LIBCPP_TYPE_VIS ios_base; @@ -116,6 +117,8 @@ template<> struct char_traits; #endif +_LIBCPP_END_NAMESPACE_CES + template class _LIBCPP_TEMPLATE_VIS allocator; template > Index: libcxx/include/iostream =================================================================== --- libcxx/include/iostream +++ libcxx/include/iostream @@ -44,6 +44,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES extern _LIBCPP_FUNC_VIS istream cin; extern _LIBCPP_FUNC_VIS ostream cout; @@ -57,6 +58,7 @@ extern _LIBCPP_FUNC_VIS wostream wclog; #endif +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_IOSTREAM Index: libcxx/include/locale =================================================================== --- libcxx/include/locale +++ libcxx/include/locale @@ -227,6 +227,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES #if defined(__APPLE__) || defined(__FreeBSD__) # define _LIBCPP_GET_C_LOCALE 0 @@ -4421,6 +4422,7 @@ return __rt; } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS Index: libcxx/include/regex =================================================================== --- libcxx/include/regex +++ libcxx/include/regex @@ -788,6 +788,7 @@ #define _LIBCPP_REGEX_COMPLEXITY_FACTOR 4096 _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES namespace regex_constants { @@ -1310,19 +1311,29 @@ return (__c == '_' && (__m & __regex_word)); } +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) + #define _MASK07 0xF0 + #define _MASK89 0xF8 + #define _TOLOWER(c) (c &= 0xBF) +#else + #define _MASK07 0x30 + #define _MASK89 0x38 + #define _TOLOWER(c) (c |= 0x20) +#endif + template int regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix) { - if ((__ch & 0xF8u) == 0x30) // '0' <= __ch && __ch <= '7' + if ((__ch & 0xF8u) == _MASK07) // '0' <= __ch && __ch <= '7' return __ch - '0'; if (__radix != 8) { - if ((__ch & 0xFEu) == 0x38) // '8' <= __ch && __ch <= '9' + if ((__ch & 0xFEu) == _MASK89) // '8' <= __ch && __ch <= '9' return __ch - '0'; if (__radix == 16) { - __ch |= 0x20; // tolower + _TOLOWER(__ch); // tolower if ('a' <= __ch && __ch <= 'f') return __ch - ('a' - 10); } @@ -6794,6 +6805,7 @@ return __r; } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS Index: libcxx/include/string =================================================================== --- libcxx/include/string +++ libcxx/include/string @@ -4382,6 +4382,8 @@ __lhs.swap(__rhs); } +_LIBCPP_BEGIN_NAMESPACE_CES + _LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10); _LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10); _LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10); @@ -4424,6 +4426,8 @@ _LIBCPP_FUNC_VIS wstring to_wstring(long double __val); #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_END_NAMESPACE_CES + template _LIBCPP_TEMPLATE_DATA_VIS const typename basic_string<_CharT, _Traits, _Allocator>::size_type Index: libcxx/include/strstream =================================================================== --- libcxx/include/strstream +++ libcxx/include/strstream @@ -138,6 +138,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES class _LIBCPP_TYPE_VIS strstreambuf : public streambuf @@ -402,6 +403,7 @@ strstreambuf __sb_; // exposition only }; +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STRSTREAM Index: libcxx/src/any.cpp =================================================================== --- libcxx/src/any.cpp +++ libcxx/src/any.cpp @@ -7,11 +7,10 @@ //===----------------------------------------------------------------------===// #include "any" +#include "include/error_message.h" namespace std { -const char* bad_any_cast::what() const noexcept { - return "bad any cast"; -} +const char* bad_any_cast::what() const noexcept { return getRuntimeErrorString(RM_BAD_ANY_CAST); } } @@ -27,8 +26,6 @@ virtual const char* what() const noexcept; }; -const char* bad_any_cast::what() const noexcept { - return "bad any cast"; -} +const char* bad_any_cast::what() const noexcept { return getRuntimeErrorString(RM_BAD_ANY_CAST); } _LIBCPP_END_NAMESPACE_LFTS Index: libcxx/src/charconv.cpp =================================================================== --- libcxx/src/charconv.cpp +++ libcxx/src/charconv.cpp @@ -10,6 +10,7 @@ #include _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES namespace __itoa { @@ -157,4 +158,5 @@ } // namespace __itoa +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/filesystem/directory_iterator.cpp =================================================================== --- libcxx/src/filesystem/directory_iterator.cpp +++ libcxx/src/filesystem/directory_iterator.cpp @@ -101,6 +101,8 @@ using detail::ErrorHandler; +_LIBCPP_BEGIN_NAMESPACE_CES + #if defined(_LIBCPP_WIN32API) class __dir_stream { public: @@ -412,4 +414,5 @@ return false; } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_FILESYSTEM Index: libcxx/src/filesystem/operations.cpp =================================================================== --- libcxx/src/filesystem/operations.cpp +++ libcxx/src/filesystem/operations.cpp @@ -639,6 +639,7 @@ using parser::PathParser; using parser::string_view_t; +#if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) const bool _FilesystemClock::is_steady; _FilesystemClock::time_point _FilesystemClock::now() noexcept { @@ -684,6 +685,10 @@ }(); } +#endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + +_LIBCPP_BEGIN_NAMESPACE_CES + static path __do_absolute(const path& p, path* cwd, error_code* ec) { if (ec) ec->clear(); @@ -810,6 +815,8 @@ } } +_LIBCPP_END_NAMESPACE_CES + namespace detail { namespace { @@ -891,6 +898,8 @@ } // end anonymous namespace } // end namespace detail +_LIBCPP_BEGIN_NAMESPACE_CES + bool __copy_file(const path& from, const path& to, copy_options options, error_code* ec) { using detail::FileDescriptor; @@ -1852,6 +1861,8 @@ return CompareEndState(&LHS, &RHS); } +_LIBCPP_END_NAMESPACE_CES + //////////////////////////////////////////////////////////////////////////// // path.nonmembers size_t hash_value(const path& __p) noexcept { @@ -1865,6 +1876,8 @@ return hash_value; } +_LIBCPP_BEGIN_NAMESPACE_CES + //////////////////////////////////////////////////////////////////////////// // path.itr path::iterator path::begin() const { @@ -1990,4 +2003,5 @@ return failure_ec; } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_FILESYSTEM Index: libcxx/src/functional.cpp =================================================================== --- libcxx/src/functional.cpp +++ libcxx/src/functional.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "functional" +#include "include/error_message.h" _LIBCPP_BEGIN_NAMESPACE_STD @@ -15,11 +16,7 @@ { } -const char* -bad_function_call::what() const noexcept -{ - return "std::bad_function_call"; -} +const char* bad_function_call::what() const noexcept { return getRuntimeErrorString(RM_BAD_FUNCTION_CALL); } #endif _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/future.cpp =================================================================== --- libcxx/src/future.cpp +++ libcxx/src/future.cpp @@ -12,6 +12,7 @@ #include "future" #include "string" +#include "include/error_message.h" _LIBCPP_BEGIN_NAMESPACE_STD @@ -44,18 +45,15 @@ { case future_errc(0): // For backwards compatibility with C++11 (LWG 2056) case future_errc::broken_promise: - return string("The associated promise has been destructed prior " - "to the associated state becoming ready."); + return string(getRuntimeErrorString(RM_BROKEN_PROMISE)); case future_errc::future_already_retrieved: - return string("The future has already been retrieved from " - "the promise or packaged_task."); + return string(getRuntimeErrorString(RM_FUTURE_ALREADY_RETRIEVED)); case future_errc::promise_already_satisfied: - return string("The state of the promise has already been set."); + return string(getRuntimeErrorString(RM_PROMISE_ALREADY_SATISFIED)); case future_errc::no_state: - return string("Operation not permitted on an object without " - "an associated state."); + return string(getRuntimeErrorString(RM_NO_STATE)); } - return string("unspecified future_errc value\n"); + return string(getRuntimeErrorString(RM_UNSPECIFIED_FEV)); } #if defined(__clang__) Index: libcxx/src/include/error_message.h =================================================================== --- /dev/null +++ libcxx/src/include/error_message.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===//// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===//// + +#ifndef ERROR_MESSAGE_H +#define ERROR_MESSAGE_H + +#ifdef __MVS__ +# define _AE_BIMODAL 1 +# include <_Nascii.h> +#endif + +#include "__config" + +#define ErrorList \ + ErrMsg(RM_BROKEN_PROMISE, \ + "The associated promise has been destructed prior to the associated state becoming ready."), \ + ErrMsg(RM_FUTURE_ALREADY_RETRIEVED, "The future has already been retrieved from the promise or packaged_task."), \ + ErrMsg(RM_PROMISE_ALREADY_SATISFIED, "The state of the promise has already been set."), \ + ErrMsg(RM_NO_STATE, "Operation not permitted on an object without an associated state."), \ + ErrMsg(RM_UNSPECIFIED_FEV, "unspecified future_errc value\n"), \ + ErrMsg(RM_PURE_VIRTUAL_FUNCTION, "Pure virtual function called!"), \ + ErrMsg(RM_DELETED_VIRTUAL_FUNCTION, "Deleted virtual function called!"), \ + ErrMsg(RM_WHAT_BAD_OPTIONAL, "bad_optional_access"), \ + ErrMsg(RM_LIBCXXABI, "libc++abi: "), \ + ErrMsg(RM_NL, "\n"), \ + ErrMsg(RM_UNSPECIFIED_ICE, "unspecified iostream_category error"), \ + ErrMsg(RM_STRERROR_MSG, "unexpected error from ::strerror_r"), \ + ErrMsg(RM_UNKNOWN_ERROR, "Unknown error %d"), \ + ErrMsg(RM_UNSPECIFIED_GCE, "unspecified generic_category error"), \ + ErrMsg(RM_UNSPECIFIED_SCE, "unspecified system_category error"), \ + ErrMsg(RM_BAD_ANY_CAST, "bad any cast"), \ + ErrMsg(RM_BAD_FUNCTION_CALL, "std::bad_function_call"), \ + ErrMsg(RM_BAD_WEAK_PTR, "bad_weak_ptr"), \ + ErrMsg(RM_BAD_VARIANT_ACS, "bad_variant_access"), + +#define ErrMsg(N, D) N +enum Errs { ErrorList }; +#undef ErrMsg + +#define ErrMsg(N, D) D +#ifdef __MVS__ +# pragma convert("IBM-1047") +static constexpr const char* const ErrTextEBCDIC[] = {ErrorList}; +# pragma convert(pop) +# pragma convert("ISO8859-1") +static constexpr const char* const ErrTextASCII[] = {ErrorList}; +# pragma convert(pop) +#else +static constexpr const char* const ErrText = {ErrorList}; +#endif +#undef ErrMsg + +#ifdef __MVS__ +_LIBCPP_INLINE_VISIBILITY +inline const char* getRuntimeErrorString(int error) _NOEXCEPT { + return (__isASCII() ? ErrTextASCII[error] : ErrTextEBCDIC[error]); +} +#else +_LIBCPP_INLINE_VISIBILITY +inline constexpr const char* getRuntimeErrorString(int error) _NOEXCEPT { return ErrText[error]; } +#endif + +#endif // ERROR_MESSAGE_H Index: libcxx/src/ios.cpp =================================================================== --- libcxx/src/ios.cpp +++ libcxx/src/ios.cpp @@ -15,6 +15,7 @@ #include "__locale" #include "algorithm" #include "include/config_elast.h" +#include "include/error_message.h" #include "limits" #include "memory" #include "new" @@ -22,6 +23,7 @@ #include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES class _LIBCPP_HIDDEN __iostream_category : public __do_message @@ -46,7 +48,7 @@ #endif // _LIBCPP_ELAST ) return __do_message::message(ev); - return string("unspecified iostream_category error"); + return string(getRuntimeErrorString(RM_UNSPECIFIED_ICE)); } const error_category& @@ -438,4 +440,5 @@ return r; } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/iostream.cpp =================================================================== --- libcxx/src/iostream.cpp +++ libcxx/src/iostream.cpp @@ -16,6 +16,7 @@ #define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE) _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES _ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) @@ -164,4 +165,5 @@ { } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/locale.cpp =================================================================== --- libcxx/src/locale.cpp +++ libcxx/src/locale.cpp @@ -53,6 +53,7 @@ #endif _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES struct __libcpp_unique_locale { __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {} @@ -898,7 +899,7 @@ #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) return isascii(c) ? ctype::__classic_upper_table()[c] : c; #else return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; @@ -912,7 +913,7 @@ #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) *low = isascii(*low) ? ctype::__classic_upper_table()[*low] : *low; #else @@ -927,7 +928,7 @@ #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) return isascii(c) ? ctype::__classic_lower_table()[c] : c; #else return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; @@ -941,7 +942,7 @@ #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__MVS__) *low = isascii(*low) ? ctype::__classic_lower_table()[*low] : *low; #else @@ -1011,7 +1012,7 @@ static_cast(_DefaultRuneLocale.__mapupper[static_cast(c)]) : c; #elif defined(__NetBSD__) return static_cast(__classic_upper_table()[static_cast(c)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) return isascii(c) ? static_cast(__classic_upper_table()[static_cast(c)]) : c; #else @@ -1028,7 +1029,7 @@ static_cast(_DefaultRuneLocale.__mapupper[static_cast(*low)]) : *low; #elif defined(__NetBSD__) *low = static_cast(__classic_upper_table()[static_cast(*low)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) *low = isascii(*low) ? static_cast(__classic_upper_table()[static_cast(*low)]) : *low; #else @@ -1045,7 +1046,7 @@ static_cast(_DefaultRuneLocale.__maplower[static_cast(c)]) : c; #elif defined(__NetBSD__) return static_cast(__classic_lower_table()[static_cast(c)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) return isascii(c) ? static_cast(__classic_lower_table()[static_cast(c)]) : c; #else @@ -1061,7 +1062,7 @@ *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(*low)]) : *low; #elif defined(__NetBSD__) *low = static_cast(__classic_lower_table()[static_cast(*low)]); -#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) +#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__) *low = isascii(*low) ? static_cast(__classic_lower_table()[static_cast(*low)]) : *low; #else *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; @@ -1209,6 +1210,12 @@ return _ctype_ + 1; #elif defined(_AIX) return (const unsigned int *)__lc_ctype_ptr->obj->mask; +#elif defined(__MVS__) +#if defined(__NATIVE_ASCII_F) + return const_cast::mask*> (__OBJ_DATA(__lc_ctype_a)->mask); +#else + return const_cast::mask*> (__ctypec); +#endif #else // Platform not supported: abort so the person doing the port knows what to // fix @@ -1257,7 +1264,26 @@ { return *__ctype_toupper_loc(); } -#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ +#elif defined(__MVS__) +const unsigned short* +ctype::__classic_lower_table() _NOEXCEPT +{ +#if defined(__NATIVE_ASCII_F) + return const_cast(__OBJ_DATA(__lc_ctype_a)->lower); +#else + return const_cast(__ctype + __TOLOWER_INDEX); +#endif +} +const unsigned short * +ctype::__classic_upper_table() _NOEXCEPT +{ +#if defined(__NATIVE_ASCII_F) + return const_cast(__OBJ_DATA(__lc_ctype_a)->upper); +#else + return const_cast(__ctype + __TOUPPER_INDEX); +#endif +} +#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__ // template <> class ctype_byname @@ -6478,19 +6504,10 @@ void __do_nothing(void*) {} -void __throw_runtime_error(const char* msg) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - throw runtime_error(msg); -#else - (void)msg; - _VSTD::abort(); -#endif -} - template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate; _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate;) + template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get; _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get;) @@ -6552,4 +6569,18 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname; #endif +_LIBCPP_END_NAMESPACE_CES + +#if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) +void __throw_runtime_error(const char* msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw runtime_error(msg); +#else + (void)msg; + _VSTD::abort(); +#endif +} +#endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/memory.cpp =================================================================== --- libcxx/src/memory.cpp +++ libcxx/src/memory.cpp @@ -15,6 +15,7 @@ #endif #endif #include "include/atomic_support.h" +#include "include/error_message.h" _LIBCPP_BEGIN_NAMESPACE_STD @@ -22,11 +23,7 @@ bad_weak_ptr::~bad_weak_ptr() noexcept {} -const char* -bad_weak_ptr::what() const noexcept -{ - return "bad_weak_ptr"; -} +const char* bad_weak_ptr::what() const noexcept { return getRuntimeErrorString(RM_BAD_WEAK_PTR); } __shared_count::~__shared_count() { Index: libcxx/src/optional.cpp =================================================================== --- libcxx/src/optional.cpp +++ libcxx/src/optional.cpp @@ -8,15 +8,14 @@ #include "optional" #include "__availability" +#include "include/error_message.h" namespace std { bad_optional_access::~bad_optional_access() noexcept = default; -const char* bad_optional_access::what() const noexcept { - return "bad_optional_access"; - } +const char* bad_optional_access::what() const noexcept { return getRuntimeErrorString(RM_WHAT_BAD_OPTIONAL); } } // std Index: libcxx/src/random.cpp =================================================================== --- libcxx/src/random.cpp +++ libcxx/src/random.cpp @@ -91,6 +91,8 @@ __throw_system_error(errno, ("random_device failed to open " + __token).c_str()); } +#if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + random_device::~random_device() { close(__f_); @@ -119,6 +121,8 @@ return r; } +#endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + #elif defined(_LIBCPP_USING_NACL_RANDOM) random_device::random_device(const string& __token) @@ -174,6 +178,7 @@ #error "Random device not implemented for this architecture" #endif +#if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) double random_device::entropy() const noexcept { @@ -195,5 +200,6 @@ return 0; #endif } +#endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/regex.cpp =================================================================== --- libcxx/src/regex.cpp +++ libcxx/src/regex.cpp @@ -11,6 +11,7 @@ #include "iterator" _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES static const char* @@ -76,6 +77,125 @@ char char_; }; +#if defined(__MVS__) && !defined(__NATIVE_ASCII_F) +// EBCDIC IBM-1047 +// Sorted via the EBCDIC collating sequence +const collationnames collatenames[] = +{ + {"a", 0x81}, + {"alert", 0x2f}, + {"ampersand", 0x50}, + {"apostrophe", 0x7d}, + {"asterisk", 0x5c}, + {"b", 0x82}, + {"backslash", 0xe0}, + {"backspace", 0x16}, + {"c", 0x83}, + {"carriage-return", 0xd}, + {"circumflex", 0x5f}, + {"circumflex-accent", 0x5f}, + {"colon", 0x7a}, + {"comma", 0x6b}, + {"commercial-at", 0x7c}, + {"d", 0x84}, + {"dollar-sign", 0x5b}, + {"e", 0x85}, + {"eight", 0xf8}, + {"equals-sign", 0x7e}, + {"exclamation-mark", 0x5a}, + {"f", 0x86}, + {"five", 0xf5}, + {"form-feed", 0xc}, + {"four", 0xf4}, + {"full-stop", 0x4b}, + {"g", 0x87}, + {"grave-accent", 0x79}, + {"greater-than-sign", 0x6e}, + {"h", 0x88}, + {"hyphen", 0x60}, + {"hyphen-minus", 0x60}, + {"i", 0x89}, + {"j", 0x91}, + {"k", 0x92}, + {"l", 0x93}, + {"left-brace", 0xc0}, + {"left-curly-bracket", 0xc0}, + {"left-parenthesis", 0x4d}, + {"left-square-bracket", 0xad}, + {"less-than-sign", 0x4c}, + {"low-line", 0x6d}, + {"m", 0x94}, + {"n", 0x95}, + {"newline", 0x15}, + {"nine", 0xf9}, + {"number-sign", 0x7b}, + {"o", 0x96}, + {"one", 0xf1}, + {"p", 0x97}, + {"percent-sign", 0x6c}, + {"period", 0x4b}, + {"plus-sign", 0x4e}, + {"q", 0x98}, + {"question-mark", 0x6f}, + {"quotation-mark", 0x7f}, + {"r", 0x99}, + {"reverse-solidus", 0xe0}, + {"right-brace", 0xd0}, + {"right-curly-bracket", 0xd0}, + {"right-parenthesis", 0x5d}, + {"right-square-bracket", 0xbd}, + {"s", 0xa2}, + {"semicolon", 0x5e}, + {"seven", 0xf7}, + {"six", 0xf6}, + {"slash", 0x61}, + {"solidus", 0x61}, + {"space", 0x40}, + {"t", 0xa3}, + {"tab", 0x5}, + {"three", 0xf3}, + {"tilde", 0xa1}, + {"two", 0xf2}, + {"u", 0xa4}, + {"underscore", 0x6d}, + {"v", 0xa5}, + {"vertical-line", 0x4f}, + {"vertical-tab", 0xb}, + {"w", 0xa6}, + {"x", 0xa7}, + {"y", 0xa8}, + {"z", 0xa9}, + {"zero", 0xf0}, + {"A", 0xc1}, + {"B", 0xc2}, + {"C", 0xc3}, + {"D", 0xc4}, + {"E", 0xc5}, + {"F", 0xc6}, + {"G", 0xc7}, + {"H", 0xc8}, + {"I", 0xc9}, + {"J", 0xd1}, + {"K", 0xd2}, + {"L", 0xd3}, + {"M", 0xd4}, + {"N", 0xd5}, + {"NUL", 0}, + {"O", 0xd6}, + {"P", 0xd7}, + {"Q", 0xd8}, + {"R", 0xd9}, + {"S", 0xe2}, + {"T", 0xe3}, + {"U", 0xe4}, + {"V", 0xe5}, + {"W", 0xe6}, + {"X", 0xe7}, + {"Y", 0xe8}, + {"Z", 0xe9} +}; +#else +// ASCII const collationnames collatenames[] = { {"A", 0x41}, @@ -190,6 +310,7 @@ {"z", 0x7a}, {"zero", 0x30} }; +#endif struct classnames { @@ -313,4 +434,5 @@ } } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/string.cpp =================================================================== --- libcxx/src/string.cpp +++ libcxx/src/string.cpp @@ -269,6 +269,8 @@ } // unnamed namespace +_LIBCPP_BEGIN_NAMESPACE_CES + int stoi(const string& str, size_t* idx, int base) { @@ -498,4 +500,5 @@ wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string()(), L"%Lf", val); } #endif +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/strstream.cpp =================================================================== --- libcxx/src/strstream.cpp +++ libcxx/src/strstream.cpp @@ -15,6 +15,7 @@ #include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES strstreambuf::strstreambuf(streamsize __alsize) : __strmode_(__dynamic), @@ -332,4 +333,5 @@ { } +_LIBCPP_END_NAMESPACE_CES _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/support/ibm/xlocale_zos.cpp =================================================================== --- libcxx/src/support/ibm/xlocale_zos.cpp +++ libcxx/src/support/ibm/xlocale_zos.cpp @@ -10,9 +10,8 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus +_LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_CES locale_t newlocale(int category_mask, const char* locale, locale_t base) { // Maintain current locale name(s) to restore later. @@ -132,6 +131,5 @@ return previous_loc; } -#ifdef __cplusplus -} -#endif // __cplusplus +_LIBCPP_END_NAMESPACE_CES +_LIBCPP_END_NAMESPACE_STD Index: libcxx/src/support/runtime/stdexcept_default.ipp =================================================================== --- libcxx/src/support/runtime/stdexcept_default.ipp +++ libcxx/src/support/runtime/stdexcept_default.ipp @@ -21,6 +21,7 @@ logic_error::logic_error(const string& msg) : __imp_(msg.c_str()) {} +#if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) logic_error::logic_error(const char* msg) : __imp_(msg) {} logic_error::logic_error(const logic_error& le) noexcept : __imp_(le.__imp_) {} @@ -30,8 +31,6 @@ return *this; } -runtime_error::runtime_error(const string& msg) : __imp_(msg.c_str()) {} - runtime_error::runtime_error(const char* msg) : __imp_(msg) {} runtime_error::runtime_error(const runtime_error& re) noexcept @@ -41,6 +40,9 @@ __imp_ = re.__imp_; return *this; } +#endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) +runtime_error::runtime_error(const string& msg) : __imp_(msg.c_str()) {} + #if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX) Index: libcxx/src/system_error.cpp =================================================================== --- libcxx/src/system_error.cpp +++ libcxx/src/system_error.cpp @@ -6,11 +6,16 @@ // //===----------------------------------------------------------------------===// +#if defined(__MVS__) +#define _AE_BIMODAL 1 +#endif + #include "__config" #include "system_error" #include "include/config_elast.h" +#include "include/error_message.h" #include "cerrno" #include "cstring" #include "cstdio" @@ -26,7 +31,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // class error_category - +#if !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) #if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) error_category::error_category() noexcept { @@ -100,7 +105,8 @@ if (new_errno == EINVAL) return ""; - _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r"); + _LIBCPP_ASSERT(new_errno == ERANGE, getRuntimeErrorString(RM_STRERROR_MSG)); + // FIXME maybe? 'strerror_buff_size' is likely to exceed the // maximum error size so ERANGE shouldn't be returned. std::abort(); @@ -114,10 +120,22 @@ // system_error functions not modify errno). const int old_errno = errno; const char *error_message = handle_strerror_r_return( - ::strerror_r(ev, buffer, strerror_buff_size), buffer); +#if defined(__MVS__) + (__isASCII() ? __strerror_r_a : __strerror_r_e) +#else + ::strerror_r +#endif + (ev, buffer, strerror_buff_size), buffer); // If we didn't get any message, print one now. if (!error_message[0]) { - std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev); +#if defined(__MVS__) + if (__isASCII()) + __snprintf_a(buffer, strerror_buff_size, getRuntimeErrorString(RM_UNKNOWN_ERROR), ev); + else + __snprintf_e(buffer, strerror_buff_size, getRuntimeErrorString(RM_UNKNOWN_ERROR), ev); +#else + std::snprintf(buffer, strerror_buff_size, getRuntimeErrorString(RM_UNKNOWN_ERROR), ev); +#endif error_message = buffer; } errno = old_errno; @@ -155,9 +173,9 @@ __generic_error_category::message(int ev) const { #ifdef _LIBCPP_ELAST - if (ev > _LIBCPP_ELAST) - return string("unspecified generic_category error"); -#endif // _LIBCPP_ELAST + if (ev > _LIBCPP_ELAST) + return string(getRuntimeErrorString(RM_UNSPECIFIED_GCE)); +#endif // _LIBCPP_ELAST return __do_message::message(ev); } @@ -187,9 +205,9 @@ __system_error_category::message(int ev) const { #ifdef _LIBCPP_ELAST - if (ev > _LIBCPP_ELAST) - return string("unspecified system_category error"); -#endif // _LIBCPP_ELAST + if (ev > _LIBCPP_ELAST) + return string(getRuntimeErrorString(RM_UNSPECIFIED_SCE)); +#endif // _LIBCPP_ELAST return __do_message::message(ev); } @@ -228,24 +246,6 @@ // system_error -string -system_error::__init(const error_code& ec, string what_arg) -{ - if (ec) - { - if (!what_arg.empty()) - what_arg += ": "; - what_arg += ec.message(); - } - return what_arg; -} - -system_error::system_error(error_code ec, const string& what_arg) - : runtime_error(__init(ec, what_arg)), - __ec_(ec) -{ -} - system_error::system_error(error_code ec, const char* what_arg) : runtime_error(__init(ec, what_arg)), __ec_(ec) @@ -258,12 +258,6 @@ { } -system_error::system_error(int ev, const error_category& ecat, const string& what_arg) - : runtime_error(__init(error_code(ev, ecat), what_arg)), - __ec_(error_code(ev, ecat)) -{ -} - system_error::system_error(int ev, const error_category& ecat, const char* what_arg) : runtime_error(__init(error_code(ev, ecat), what_arg)), __ec_(error_code(ev, ecat)) @@ -292,4 +286,30 @@ #endif } +#endif // !defined(_LIBCPP_ADDITIONAL_CHAR_ENCODING) + +string +system_error::__init(const error_code& ec, string what_arg) +{ + if (ec) + { + if (!what_arg.empty()) + what_arg += ": "; + what_arg += ec.message(); + } + return what_arg; +} + +system_error::system_error(error_code ec, const string& what_arg) + : runtime_error(__init(ec, what_arg)), + __ec_(ec) +{ +} + +system_error::system_error(int ev, const error_category& ecat, const string& what_arg) + : runtime_error(__init(error_code(ev, ecat), what_arg)), + __ec_(error_code(ev, ecat)) +{ +} + _LIBCPP_END_NAMESPACE_STD Index: libcxx/src/variant.cpp =================================================================== --- libcxx/src/variant.cpp +++ libcxx/src/variant.cpp @@ -7,11 +7,10 @@ //===----------------------------------------------------------------------===// #include "variant" +#include "include/error_message.h" namespace std { -const char* bad_variant_access::what() const noexcept { - return "bad_variant_access"; -} +const char* bad_variant_access::what() const noexcept { return getRuntimeErrorString(RM_BAD_VARIANT_ACS); } } // namespace std Index: libcxxabi/src/abort_message.cpp =================================================================== --- libcxxabi/src/abort_message.cpp +++ libcxxabi/src/abort_message.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include #include #include #include @@ -33,12 +34,30 @@ // formatting into the variable-sized buffer fails. #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL) { - fprintf(stderr, "libc++abi: "); - va_list list; - va_start(list, format); - vfprintf(stderr, format, list); - va_end(list); - fprintf(stderr, "\n"); +#if defined(__MVS__) + if (__isASCII()) + __fprintf_a(stderr, getRuntimeErrorString(RM_LIBCXXABI)); + else + __fprintf_e(stderr, getRuntimeErrorString(RM_LIBCXXABI)); + va_list list; + va_start(list, format); + if (__isASCII()) + __vfprintf_a(stderr, format, list); + else + __vfprintf_e(stderr, format, list); + va_end(list); + if (__isASCII()) + __fprintf_a(stderr, getRuntimeErrorString(RM_NL)); + else + __fprintf_e(stderr, getRuntimeErrorString(RM_NL)); +#else + fprintf(stderr, getRuntimeErrorString(RM_LIBCXXABI)); + va_list list; + va_start(list, format); + vfprintf(stderr, format, list); + va_end(list); + fprintf(stderr, getRuntimeErrorString(RM_NL)); +#endif } #endif Index: libcxxabi/src/cxa_virtual.cpp =================================================================== --- libcxxabi/src/cxa_virtual.cpp +++ libcxxabi/src/cxa_virtual.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include #include "cxxabi.h" #include "abort_message.h" @@ -13,12 +14,12 @@ extern "C" { _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void) { - abort_message("Pure virtual function called!"); + abort_message(getRuntimeErrorString(RM_PURE_VIRTUAL_FUNCTION)); } _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void) { - abort_message("Deleted virtual function called!"); + abort_message(getRuntimeErrorString(RM_DELETED_VIRTUAL_FUNCTION)); } } // extern "C" } // abi