[libcxx-commits] [libcxx] 7e7013c - [libc++][cuchar] Declare std::c8rtomb and std::mbrtoc8 in <cuchar> if available.

Tom Honermann via libcxx-commits libcxx-commits at lists.llvm.org
Sat Sep 10 18:11:12 PDT 2022


Author: Tom Honermann
Date: 2022-09-10T21:10:33-04:00
New Revision: 7e7013c5d4b1b3996c8dba668c5a94bb33b2999b

URL: https://github.com/llvm/llvm-project/commit/7e7013c5d4b1b3996c8dba668c5a94bb33b2999b
DIFF: https://github.com/llvm/llvm-project/commit/7e7013c5d4b1b3996c8dba668c5a94bb33b2999b.diff

LOG: [libc++][cuchar] Declare std::c8rtomb and std::mbrtoc8 in <cuchar> if available.

This change implements the C library dependent portions of P0482R6
(char8_t: A type for UTF-8 characters and strings (Revision 6)) by
declaring std::c8rtomb() and std::mbrtoc8() in the <cuchar> header
when implementations are provided by the C library as specified by
WG14 N2653 (char8_t: A type for UTF-8 characters and strings
(Revision 1)) as adopted for C23.

A _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 macro is defined by the libc++ __config
header unless it is known that the C library provides these functions
in the current compilation mode. This macro is used for testing purposes
and may be of use to libc++ users. At present, the only C library known
to implement these functions is GNU libc as of its 2.36 release.

Reviewed By: ldionne

Differential Revision: https://reviews.llvm.org/D130946

Added: 
    libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp

Modified: 
    libcxx/docs/ReleaseNotes.rst
    libcxx/docs/Status/Cxx20.rst
    libcxx/docs/Status/Cxx20Papers.csv
    libcxx/include/__config
    libcxx/include/cuchar
    libcxx/include/uchar.h
    libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
    libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
    libcxx/test/support/test_macros.h

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 9c46642e703cf..f745a770db229 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -44,6 +44,9 @@ Implemented Papers
 
 Improvements and New Features
 -----------------------------
+- Declarations of ``std::c8rtomb()`` and ``std::mbrtoc8()`` from P0482R6 are
+  now provided when implementations in the global namespace are provided by
+  the C library.
 
 Deprecations and Removals
 -------------------------

diff  --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst
index 43d29c5c9d886..90f2acc6a7bb8 100644
--- a/libcxx/docs/Status/Cxx20.rst
+++ b/libcxx/docs/Status/Cxx20.rst
@@ -49,6 +49,8 @@ Paper Status
    .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
    .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0.
    .. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet.
+   .. [#note-P0482] P0482: Declarations of ``std::pmr::u8string`` and ``std::hash<std::pmr::u8string>`` are blocked pending implementation
+      of polymorphic allocator support from P0220.
 
 
 .. _issues-status-cxx20:

diff  --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv
index f9c58b2be7384..ed1d0cea6f109 100644
--- a/libcxx/docs/Status/Cxx20Papers.csv
+++ b/libcxx/docs/Status/Cxx20Papers.csv
@@ -53,7 +53,7 @@
 "`P0318R1 <https://wg21.link/P0318R1>`__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0"
 "`P0356R5 <https://wg21.link/P0356R5>`__","LWG","Simplified partial function application","San Diego","|Complete|","13.0"
 "`P0357R3 <https://wg21.link/P0357R3>`__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0"
-"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|In Progress|",""
+"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|Partial| [#note-P0482]_","16.0"
 "`P0487R1 <https://wg21.link/P0487R1>`__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\  (LWG 2499)","San Diego","|Complete|","8.0"
 "`P0591R4 <https://wg21.link/P0591R4>`__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *",""
 "`P0595R2 <https://wg21.link/P0595R2>`__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0"

diff  --git a/libcxx/include/__config b/libcxx/include/__config
index 364607ef1c864..a6f3b4e88aa1d 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1208,6 +1208,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_PACKED
 #  endif
 
+// c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these
+// functions is gradually being added to existing C libraries. The conditions
+// below check for known C library versions and conditions under which these
+// functions are declared by the C library.
+#  define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
+// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
+// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately,
+// determining the latter depends on internal GNU libc details. If the
+// __cpp_char8_t feature test macro is not defined, then a char8_t typedef
+// will be declared as well.
+#  if defined(_LIBCPP_GLIBC_PREREQ)
+#    if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X))
+#      undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
+#    endif
+#  endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP___CONFIG

diff  --git a/libcxx/include/cuchar b/libcxx/include/cuchar
index b685f470301de..93e657e84b6dc 100644
--- a/libcxx/include/cuchar
+++ b/libcxx/include/cuchar
@@ -25,6 +25,8 @@ Types:
   mbstate_t
   size_t
 
+size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps);   // since C++20
+size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps);                     // since C++20
 size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
 size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
 size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
@@ -58,6 +60,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
 using ::size_t _LIBCPP_USING_IF_EXISTS;
 
+#  if !defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
+using ::mbrtoc8 _LIBCPP_USING_IF_EXISTS;
+using ::c8rtomb _LIBCPP_USING_IF_EXISTS;
+#  endif
 using ::mbrtoc16 _LIBCPP_USING_IF_EXISTS;
 using ::c16rtomb _LIBCPP_USING_IF_EXISTS;
 using ::mbrtoc32 _LIBCPP_USING_IF_EXISTS;

diff  --git a/libcxx/include/uchar.h b/libcxx/include/uchar.h
index bb152c72cb3c6..3a51bb7a9f61f 100644
--- a/libcxx/include/uchar.h
+++ b/libcxx/include/uchar.h
@@ -23,6 +23,8 @@
   mbstate_t
   size_t
 
+size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps);     // since C++20
+size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps);                       // since C++20
 size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
 size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
 size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);

diff  --git a/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp b/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
index f031ed11a899c..016e51d99c597 100644
--- a/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
+++ b/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
@@ -23,6 +23,11 @@
 // __STDC_UTF_16__ may or may not be defined by the C standard library
 // __STDC_UTF_32__ may or may not be defined by the C standard library
 
+#if !defined(TEST_HAS_NO_C8RTOMB_MBRTOC8)
+ASSERT_SAME_TYPE(size_t, decltype(mbrtoc8((char8_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
+ASSERT_SAME_TYPE(size_t, decltype(c8rtomb((char*)0, (char8_t)0, (mbstate_t*)0)));
+#endif
+
 ASSERT_SAME_TYPE(size_t, decltype(mbrtoc16((char16_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
 ASSERT_SAME_TYPE(size_t, decltype(c16rtomb((char*)0, (char16_t)0, (mbstate_t*)0)));
 

diff  --git a/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp b/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
index 388aa20ac0c44..909f2c025bdf8 100644
--- a/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
+++ b/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
@@ -20,11 +20,14 @@
 
 #include "test_macros.h"
 
-// TODO: Implement mbrtoc8 and c8rtomb, and add tests for those
-
 // __STDC_UTF_16__ may or may not be defined by the C standard library
 // __STDC_UTF_32__ may or may not be defined by the C standard library
 
+#if !defined(TEST_HAS_NO_C8RTOMB_MBRTOC8)
+ASSERT_SAME_TYPE(size_t, decltype(std::mbrtoc8((char8_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
+ASSERT_SAME_TYPE(size_t, decltype(std::c8rtomb((char*)0, (char8_t)0, (mbstate_t*)0)));
+#endif
+
 ASSERT_SAME_TYPE(size_t, decltype(std::mbrtoc16((char16_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
 ASSERT_SAME_TYPE(size_t, decltype(std::c16rtomb((char*)0, (char16_t)0, (mbstate_t*)0)));
 

diff  --git a/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
new file mode 100644
index 0000000000000..f39aef43c2cb8
--- /dev/null
+++ b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// The system-provided <uchar.h> seems to be broken on AIX:
+//   error: 'error' diagnostics seen but not expected:
+//     File /usr/include/uchar.h Line 38: cannot combine with previous 'type-name' declaration specifier
+//     File /usr/include/uchar.h Line 39: cannot combine with previous 'type-name' declaration specifier
+//   2 errors generated.
+// XFAIL: LIBCXX-AIX-FIXME
+
+#include <uchar.h>
+
+using U = decltype(::c8rtomb);
+using V = decltype(::mbrtoc8);
+#if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
+// expected-error at -3 {{no member named 'c8rtomb' in the global namespace}}
+// expected-error at -3 {{no member named 'mbrtoc8' in the global namespace}}
+#else
+// expected-no-diagnostics
+#endif

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 7f7c6832a2565..0e0500b58d446 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -391,6 +391,10 @@ inline void DoNotOptimize(Tp const& value) {
 #  define TEST_HAS_NO_FGETPOS_FSETPOS
 #endif
 
+#if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
+#  define TEST_HAS_NO_C8RTOMB_MBRTOC8
+#endif
+
 #if defined(TEST_COMPILER_CLANG)
 #  define TEST_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
 #  define TEST_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")


        


More information about the libcxx-commits mailing list