[libc-commits] [libc] [libc] Add iswctype and wctype (PR #191178)
Zile Xiong via libc-commits
libc-commits at lists.llvm.org
Thu Apr 9 18:05:21 PDT 2026
https://github.com/xiongzile updated https://github.com/llvm/llvm-project/pull/191178
>From c1210547afc70ffa5bf4bab051bc3d6c249ac2b6 Mon Sep 17 00:00:00 2001
From: Zile Xiong <xiongzile99 at gmail.com>
Date: Thu, 9 Apr 2026 15:03:36 +0800
Subject: [PATCH 1/2] [libc] Add iswctype and wctype
Implement the iswctype and wctype functions from <wctype.h>.
- Add wctype_t type definition.
- Implement wctype to map property strings to classification descriptors.
- Implement iswctype as a dispatcher over existing wide character
classification functions.
- Add corresponding entrypoints and unit tests.
Refs: https://github.com/llvm/llvm-project/issues/191076
---
libc/config/baremetal/arm/entrypoints.txt | 2 +
libc/config/baremetal/riscv/entrypoints.txt | 2 +
libc/config/darwin/aarch64/entrypoints.txt | 2 +
libc/config/linux/aarch64/entrypoints.txt | 2 +
libc/config/linux/arm/entrypoints.txt | 2 +
libc/config/linux/riscv/entrypoints.txt | 2 +
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/config/windows/entrypoints.txt | 2 +
libc/hdr/types/CMakeLists.txt | 9 ++
libc/hdr/types/wctype_t.h | 24 ++++
libc/hdr/wctype_overlay.h | 70 +++++++++++
libc/include/CMakeLists.txt | 1 +
libc/include/llvm-libc-types/CMakeLists.txt | 1 +
libc/include/llvm-libc-types/wctype_t.h | 15 +++
libc/include/wctype.yaml | 14 +++
libc/src/__support/wctype_utils.h | 127 ++++++++++++++++++++
libc/src/wctype/CMakeLists.txt | 21 ++++
libc/src/wctype/iswctype.cpp | 23 ++++
libc/src/wctype/iswctype.h | 22 ++++
libc/src/wctype/wctype.cpp | 21 ++++
libc/src/wctype/wctype.h | 22 ++++
libc/test/src/wctype/CMakeLists.txt | 20 +++
libc/test/src/wctype/iswctype_test.cpp | 110 +++++++++++++++++
libc/test/src/wctype/wctype_test.cpp | 63 ++++++++++
24 files changed, 579 insertions(+)
create mode 100644 libc/hdr/types/wctype_t.h
create mode 100644 libc/hdr/wctype_overlay.h
create mode 100644 libc/include/llvm-libc-types/wctype_t.h
create mode 100644 libc/src/wctype/iswctype.cpp
create mode 100644 libc/src/wctype/iswctype.h
create mode 100644 libc/src/wctype/wctype.cpp
create mode 100644 libc/src/wctype/wctype.h
create mode 100644 libc/test/src/wctype/iswctype_test.cpp
create mode 100644 libc/test/src/wctype/wctype_test.cpp
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 4cf34764916f7..a2c22ac32e3ac 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -313,6 +313,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
# internal entrypoints
libc.startup.baremetal.init
libc.startup.baremetal.fini
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index c4a11c6f87337..d5fc6258aff11 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -310,6 +310,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
# internal entrypoints
libc.startup.baremetal.init
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 0888f4b0d922b..033183427de79 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -113,6 +113,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
)
if(LLVM_LIBC_FULL_BUILD)
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 567848795be49..73d1b5d307a97 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -385,6 +385,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
# sys/uio.h entrypoints
libc.src.sys.uio.writev
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 31dcb31c67c7a..997263f364524 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -205,6 +205,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
)
if(LLVM_LIBC_FULL_BUILD)
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 997c08ee7de9b..4c12be578b0e5 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -389,6 +389,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
# sys/uio.h entrypoints
libc.src.sys.uio.writev
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index ea1cd80a1d0f1..9bf2248e49dd9 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -439,6 +439,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
# sys/uio.h entrypoints
libc.src.sys.uio.writev
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index e8080bc97c59a..7d32fab21fdb4 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -119,6 +119,8 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wctype.iswxdigit
libc.src.wctype.iswpunct
libc.src.wctype.iswprint
+ libc.src.wctype.iswctype
+ libc.src.wctype.wctype
)
set(TARGET_LIBM_ENTRYPOINTS
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 7e1a8974fa486..7395f70c0d2aa 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -443,6 +443,15 @@ add_proxy_header_library(
libc.include.wchar
)
+
+add_proxy_header_library(
+ wctype_t
+ HDRS
+ wctype_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.wctype_t
+)
+
add_proxy_header_library(
uid_t
HDRS
diff --git a/libc/hdr/types/wctype_t.h b/libc/hdr/types/wctype_t.h
new file mode 100644
index 0000000000000..f8e09969227dd
--- /dev/null
+++ b/libc/hdr/types/wctype_t.h
@@ -0,0 +1,24 @@
+//===-- Definition of wctype_t.h
+//--------------------------------------------===//
+//
+// 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 LLVM_LIBC_HDR_TYPES_WCTYPE_T_H
+#define LLVM_LIBC_HDR_TYPES_WCTYPE_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/wctype_t.h"
+
+#else // overlay mode
+
+#include "hdr/wctype_overlay.h"
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_WCTYPE_T_H
diff --git a/libc/hdr/wctype_overlay.h b/libc/hdr/wctype_overlay.h
new file mode 100644
index 0000000000000..40a1a9a051a89
--- /dev/null
+++ b/libc/hdr/wctype_overlay.h
@@ -0,0 +1,70 @@
+//===-- Including wctype.h in overlay mode
+//---------------------------------===//
+//
+// 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 LLVM_LIBC_HDR_WCTYPE_OVERLAY_H
+#define LLVM_LIBC_HDR_WCTYPE_OVERLAY_H
+
+#ifdef LIBC_FULL_BUILD
+#error "This header should only be included in overlay mode"
+#endif
+
+// Overlay mode
+
+// glibc <wctype.h> header might provide extern inline definitions for few
+// functions, causing external alias errors. They are guarded by
+// `__USE_EXTERN_INLINES` macro. We temporarily disable `__USE_EXTERN_INLINES`
+// macro by defining `__NO_INLINE__` before including <wctype.h>.
+// And the same with `__USE_FORTIFY_LEVEL`, which will be temporarily disabled
+// with `_FORTIFY_SOURCE`.
+
+#ifdef _FORTIFY_SOURCE
+#define LIBC_OLD_FORTIFY_SOURCE _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#ifndef __NO_INLINE__
+#define __NO_INLINE__ 1
+#define LIBC_SET_NO_INLINE
+#endif
+
+#ifdef __USE_EXTERN_INLINES
+#define LIBC_OLD_USE_EXTERN_INLINES
+#undef __USE_EXTERN_INLINES
+#endif
+
+#ifdef __USE_FORTIFY_LEVEL
+#define LIBC_OLD_USE_FORTIFY_LEVEL __USE_FORTIFY_LEVEL
+#undef __USE_FORTIFY_LEVEL
+#define __USE_FORTIFY_LEVEL 0
+#endif
+
+#include <wctype.h>
+
+#ifdef LIBC_OLD_FORTIFY_SOURCE
+#define _FORTIFY_SOURCE LIBC_OLD_FORTIFY_SOURCE
+#undef LIBC_OLD_FORTIFY_SOURCE
+#endif
+
+#ifdef LIBC_SET_NO_INLINE
+#undef __NO_INLINE__
+#undef LIBC_SET_NO_INLINE
+#endif
+
+#ifdef LIBC_OLD_USE_FORTIFY_LEVEL
+#undef __USE_FORTIFY_LEVEL
+#define __USE_FORTIFY_LEVEL LIBC_OLD_USE_FORTIFY_LEVEL
+#undef LIBC_OLD_USE_FORTIFY_LEVEL
+#endif
+
+#ifdef LIBC_OLD_USE_EXTERN_INLINES
+#define __USE_EXTERN_INLINES
+#undef LIBC_OLD_USE_EXTERN_INLINES
+#endif
+
+#endif // LLVM_LIBC_HDR_WCTYPE_OVERLAY_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 774970dbb3d9d..c64cb12b8879c 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -872,6 +872,7 @@ add_header_macro(
DEPENDS
.llvm_libc_common_h
.llvm-libc-types.wint_t
+ .llvm-libc-types.wctype_t
)
add_header_macro(
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 0d6bc0982b847..ea9a507836735 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -166,6 +166,7 @@ add_header(
libc.include.llvm-libc-macros.stdint_macros
)
add_header(wint_t HDR wint_t.h)
+add_header(wctype_t HDR wctype_t.h)
add_header(sa_family_t HDR sa_family_t.h)
add_header(socklen_t HDR socklen_t.h)
add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t)
diff --git a/libc/include/llvm-libc-types/wctype_t.h b/libc/include/llvm-libc-types/wctype_t.h
new file mode 100644
index 0000000000000..b096c0061984a
--- /dev/null
+++ b/libc/include/llvm-libc-types/wctype_t.h
@@ -0,0 +1,15 @@
+//===-- Definition of wctype_t types
+//----------------------------------------===//
+//
+// 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 LLVM_LIBC_TYPES_WCTYPE_T_H
+#define LLVM_LIBC_TYPES_WCTYPE_T_H
+
+typedef unsigned int wctype_t;
+
+#endif // LLVM_LIBC_TYPES_WCTYPE_T_H
diff --git a/libc/include/wctype.yaml b/libc/include/wctype.yaml
index 932ff6ac1b138..a5163ecc2d3f2 100644
--- a/libc/include/wctype.yaml
+++ b/libc/include/wctype.yaml
@@ -1,6 +1,7 @@
header: wctype.h
types:
- type_name: wint_t
+ - type_name: wctype_t
functions:
- name: iswalpha
standards:
@@ -74,3 +75,16 @@ functions:
return_type: int
arguments:
- type: wint_t
+ - name: iswctype
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: wint_t
+ - type: wctype_t
+ - name: wctype
+ standards:
+ - stdc
+ return_type: wctype_t
+ arguments:
+ - type: const char*
diff --git a/libc/src/__support/wctype_utils.h b/libc/src/__support/wctype_utils.h
index a80c78d54c796..e2b34e600f255 100644
--- a/libc/src/__support/wctype_utils.h
+++ b/libc/src/__support/wctype_utils.h
@@ -454,6 +454,74 @@ LIBC_INLINE constexpr wchar_t toupper(wchar_t wch) {
}
}
+LIBC_INLINE constexpr unsigned int wctype(const char *property) {
+ if (!property)
+ return 0; // WCTYPE_INVALID
+
+ constexpr const char *names[] = {
+ "unknown", // 0
+ "alnum", // 1 - WCTYPE_ALNUM
+ "alpha", // 2 - WCTYPE_ALPHA
+ "blank", // 3 - WCTYPE_BLANK
+ "cntrl", // 4 - WCTYPE_CNTRL
+ "digit", // 5 - WCTYPE_DIGIT
+ "graph", // 6 - WCTYPE_GRAPH
+ "lower", // 7 - WCTYPE_LOWER
+ "print", // 8 - WCTYPE_PRINT
+ "punct", // 9 - WCTYPE_PUNCT
+ "space", // 10 - WCTYPE_SPACE
+ "upper", // 11 - WCTYPE_UPPER
+ "xdigit" // 12 - WCTYPE_XDIGIT
+ };
+
+ for (unsigned int i = 1; i < sizeof(names) / sizeof(names[0]); ++i) {
+ const char *s1 = property;
+ const char *s2 = names[i];
+
+ while (*s1 && (*s1 == *s2)) {
+ ++s1;
+ ++s2;
+ }
+
+ if (*s1 == *s2) {
+ return i;
+ }
+ }
+
+ return 0; // WCTYPE_INVALID
+}
+
+LIBC_INLINE constexpr int iswctype(wchar_t c, unsigned int desc) {
+ switch (desc) {
+ case 1:
+ return isalnum(c); // alnum
+ case 2:
+ return isalpha(c); // alpha
+ case 3:
+ return isblank(c); // blank
+ case 4:
+ return iscntrl(c); // cntrl
+ case 5:
+ return isdigit(c); // digit
+ case 6:
+ return isgraph(c); // graph
+ case 7:
+ return islower(c); // lower
+ case 8:
+ return isprint(c); // print
+ case 9:
+ return ispunct(c); // punct
+ case 10:
+ return isspace(c); // space
+ case 11:
+ return isupper(c); // upper
+ case 12:
+ return isxdigit(c); // xdigit
+ default:
+ return 0;
+ }
+}
+
} // namespace ascii
LIBC_INLINE constexpr bool islower(wchar_t wch) {
@@ -552,6 +620,65 @@ LIBC_INLINE constexpr bool isprint(wchar_t wch) {
#endif
}
+LIBC_INLINE constexpr bool iswctype(wchar_t wch, unsigned int desc) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::iswctype(wch, desc);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::iswctype(wch, desc);
+ }
+
+ const unsigned prop = lookup_properties(wch);
+
+ switch (desc) {
+ case 1: // alnum
+ return prop & PropertyFlag::ALPHA;
+
+ case 2: // alpha
+ return prop & PropertyFlag::ALPHA;
+
+ case 3: // blank
+ return prop & PropertyFlag::BLANK;
+
+ case 4: // cntrl
+ return prop & PropertyFlag::CNTRL;
+
+ case 5: // digit
+ return ascii::isdigit(wch);
+
+ case 6: // graph
+ // print && !space
+ return (prop & (PropertyFlag::PRINT | PropertyFlag::SPACE)) ==
+ PropertyFlag::PRINT;
+
+ case 7: // lower
+ return prop & PropertyFlag::LOWER;
+
+ case 8: // print
+ return prop & PropertyFlag::PRINT;
+
+ case 9: // punct
+ return prop & PropertyFlag::PUNCT;
+
+ case 10: // space
+ return prop & PropertyFlag::SPACE;
+
+ case 11: // upper
+ return prop & PropertyFlag::UPPER;
+
+ case 12: // xdigit
+ return ascii::isxdigit(wch);
+
+ default:
+ return false;
+ }
+#endif
+}
+
+LIBC_INLINE constexpr unsigned int wctype(const char *property) {
+ return ascii::wctype(property);
+}
+
LIBC_INLINE constexpr bool isxdigit(wchar_t wch) {
// Hexadecimal digits are the same in C.UTF8 as in ASCII
return ascii::isxdigit(wch);
diff --git a/libc/src/wctype/CMakeLists.txt b/libc/src/wctype/CMakeLists.txt
index 07bfed39980c2..57f9e7753a9f5 100644
--- a/libc/src/wctype/CMakeLists.txt
+++ b/libc/src/wctype/CMakeLists.txt
@@ -130,3 +130,24 @@ add_entrypoint_object(
libc.src.__support.wctype_utils
libc.hdr.types.wint_t
)
+
+add_entrypoint_object(
+ iswctype
+ SRCS
+ iswctype.cpp
+ HDRS
+ iswctype.h
+ DEPENDS
+ libc.src.__support.wctype_utils
+ libc.hdr.types.wint_t
+)
+
+add_entrypoint_object(
+ wctype
+ SRCS
+ wctype.cpp
+ HDRS
+ wctype.h
+ DEPENDS
+ libc.src.__support.wctype_utils
+)
diff --git a/libc/src/wctype/iswctype.cpp b/libc/src/wctype/iswctype.cpp
new file mode 100644
index 0000000000000..87bf0e31fe463
--- /dev/null
+++ b/libc/src/wctype/iswctype.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of iswctype ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wctype/iswctype.h"
+#include "src/__support/common.h"
+#include "src/__support/wctype_utils.h"
+
+#include "hdr/types/wctype_t.h"
+#include "hdr/types/wint_t.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, iswctype, (wint_t c, wctype_t desc)) {
+ return internal::iswctype(static_cast<wchar_t>(c),
+ static_cast<unsigned int>(desc));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wctype/iswctype.h b/libc/src/wctype/iswctype.h
new file mode 100644
index 0000000000000..10a0f3e969c8d
--- /dev/null
+++ b/libc/src/wctype/iswctype.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for iswctype ----------------------*- C++ -*-===//
+//
+// 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 LLVM_LIBC_SRC_WCTYPE_ISWCTYPE_H
+#define LLVM_LIBC_SRC_WCTYPE_ISWCTYPE_H
+
+#include "hdr/types/wctype_t.h"
+#include "hdr/types/wint_t.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iswctype(wint_t c, wctype_t desc);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCTYPE_ISWCTYPE_H
diff --git a/libc/src/wctype/wctype.cpp b/libc/src/wctype/wctype.cpp
new file mode 100644
index 0000000000000..59c28dcf5a437
--- /dev/null
+++ b/libc/src/wctype/wctype.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of wctype ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wctype/wctype.h"
+#include "src/__support/common.h"
+#include "src/__support/wctype_utils.h"
+
+#include "hdr/types/wctype_t.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(wctype_t, wctype, (const char *property)) {
+ return internal::wctype(property);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wctype/wctype.h b/libc/src/wctype/wctype.h
new file mode 100644
index 0000000000000..98300e49f7e03
--- /dev/null
+++ b/libc/src/wctype/wctype.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for iswctype ----------------------*- C++ -*-===//
+//
+// 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 LLVM_LIBC_SRC_WCTYPE_WCTYPE_H
+#define LLVM_LIBC_SRC_WCTYPE_WCTYPE_H
+
+#include "hdr/types/wctype_t.h"
+#include "hdr/types/wint_t.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+wctype_t wctype(const char *property);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCTYPE_WCTYPE_H
diff --git a/libc/test/src/wctype/CMakeLists.txt b/libc/test/src/wctype/CMakeLists.txt
index a5f85856dfb38..2d02888ad2833 100644
--- a/libc/test/src/wctype/CMakeLists.txt
+++ b/libc/test/src/wctype/CMakeLists.txt
@@ -121,3 +121,23 @@ add_libc_test(
DEPENDS
libc.src.wctype.iswprint
)
+
+add_libc_test(
+ iswctype_test
+ SUITE
+ libc_wctype_unittests
+ SRCS
+ iswctype_test.cpp
+ DEPENDS
+ libc.src.wctype.iswctype
+)
+
+add_libc_test(
+ wctype_test
+ SUITE
+ libc_wctype_unittests
+ SRCS
+ wctype_test.cpp
+ DEPENDS
+ libc.src.wctype.wctype
+)
diff --git a/libc/test/src/wctype/iswctype_test.cpp b/libc/test/src/wctype/iswctype_test.cpp
new file mode 100644
index 0000000000000..39ff350ab6673
--- /dev/null
+++ b/libc/test/src/wctype/iswctype_test.cpp
@@ -0,0 +1,110 @@
+//===-- Unittests for iswctype --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wctype/iswctype.h"
+
+#include "test/UnitTest/Test.h"
+
+// Simple tests, already properly tested in
+// libc/test/src/__support/wctype_utils_test.cpp
+
+static constexpr wctype_t WCTYPE_INVALID = static_cast<wctype_t>(0);
+static constexpr wctype_t WCTYPE_ALNUM = static_cast<wctype_t>(1);
+static constexpr wctype_t WCTYPE_ALPHA = static_cast<wctype_t>(2);
+static constexpr wctype_t WCTYPE_BLANK = static_cast<wctype_t>(3);
+static constexpr wctype_t WCTYPE_CNTRL = static_cast<wctype_t>(4);
+static constexpr wctype_t WCTYPE_DIGIT = static_cast<wctype_t>(5);
+static constexpr wctype_t WCTYPE_GRAPH = static_cast<wctype_t>(6);
+static constexpr wctype_t WCTYPE_LOWER = static_cast<wctype_t>(7);
+static constexpr wctype_t WCTYPE_PRINT = static_cast<wctype_t>(8);
+static constexpr wctype_t WCTYPE_PUNCT = static_cast<wctype_t>(9);
+static constexpr wctype_t WCTYPE_SPACE = static_cast<wctype_t>(10);
+static constexpr wctype_t WCTYPE_UPPER = static_cast<wctype_t>(11);
+static constexpr wctype_t WCTYPE_XDIGIT = static_cast<wctype_t>(12);
+
+TEST(LlvmLibciswctype, SimpleTest) {
+ using LIBC_NAMESPACE::iswctype;
+
+ // alnum
+ EXPECT_NE(iswctype('a', WCTYPE_ALNUM), 0);
+ EXPECT_NE(iswctype('Z', WCTYPE_ALNUM), 0);
+ EXPECT_NE(iswctype('5', WCTYPE_ALNUM), 0);
+ EXPECT_EQ(iswctype('!', WCTYPE_ALNUM), 0);
+
+ // alpha
+ EXPECT_NE(iswctype('a', WCTYPE_ALPHA), 0);
+ EXPECT_NE(iswctype('Z', WCTYPE_ALPHA), 0);
+ EXPECT_EQ(iswctype('1', WCTYPE_ALPHA), 0);
+ EXPECT_EQ(iswctype(' ', WCTYPE_ALPHA), 0);
+
+ // blank
+ EXPECT_NE(iswctype(' ', WCTYPE_BLANK), 0);
+ EXPECT_NE(iswctype('\t', WCTYPE_BLANK), 0);
+ EXPECT_EQ(iswctype('\n', WCTYPE_BLANK), 0);
+ EXPECT_EQ(iswctype('A', WCTYPE_BLANK), 0);
+
+ // cntrl
+ EXPECT_NE(iswctype('\0', WCTYPE_CNTRL), 0);
+ EXPECT_NE(iswctype('\n', WCTYPE_CNTRL), 0);
+ EXPECT_NE(iswctype(0x7f, WCTYPE_CNTRL), 0);
+ EXPECT_EQ(iswctype('A', WCTYPE_CNTRL), 0);
+
+ // digit
+ EXPECT_NE(iswctype('0', WCTYPE_DIGIT), 0);
+ EXPECT_NE(iswctype('9', WCTYPE_DIGIT), 0);
+ EXPECT_EQ(iswctype('a', WCTYPE_DIGIT), 0);
+ EXPECT_EQ(iswctype(' ', WCTYPE_DIGIT), 0);
+
+ // graph
+ EXPECT_NE(iswctype('A', WCTYPE_GRAPH), 0);
+ EXPECT_NE(iswctype('1', WCTYPE_GRAPH), 0);
+ EXPECT_NE(iswctype('!', WCTYPE_GRAPH), 0);
+ EXPECT_EQ(iswctype(' ', WCTYPE_GRAPH), 0);
+
+ // lower
+ EXPECT_NE(iswctype('a', WCTYPE_LOWER), 0);
+ EXPECT_NE(iswctype('z', WCTYPE_LOWER), 0);
+ EXPECT_EQ(iswctype('A', WCTYPE_LOWER), 0);
+ EXPECT_EQ(iswctype('1', WCTYPE_LOWER), 0);
+
+ // print
+ EXPECT_NE(iswctype(' ', WCTYPE_PRINT), 0);
+ EXPECT_NE(iswctype('A', WCTYPE_PRINT), 0);
+ EXPECT_NE(iswctype('~', WCTYPE_PRINT), 0);
+ EXPECT_EQ(iswctype('\n', WCTYPE_PRINT), 0);
+
+ // punct
+ EXPECT_NE(iswctype('!', WCTYPE_PUNCT), 0);
+ EXPECT_NE(iswctype('?', WCTYPE_PUNCT), 0);
+ EXPECT_EQ(iswctype('a', WCTYPE_PUNCT), 0);
+ EXPECT_EQ(iswctype('1', WCTYPE_PUNCT), 0);
+
+ // space
+ EXPECT_NE(iswctype(' ', WCTYPE_SPACE), 0);
+ EXPECT_NE(iswctype('\t', WCTYPE_SPACE), 0);
+ EXPECT_NE(iswctype('\n', WCTYPE_SPACE), 0);
+ EXPECT_EQ(iswctype('A', WCTYPE_SPACE), 0);
+
+ // upper
+ EXPECT_NE(iswctype('A', WCTYPE_UPPER), 0);
+ EXPECT_NE(iswctype('Z', WCTYPE_UPPER), 0);
+ EXPECT_EQ(iswctype('a', WCTYPE_UPPER), 0);
+ EXPECT_EQ(iswctype('1', WCTYPE_UPPER), 0);
+
+ // xdigit
+ EXPECT_NE(iswctype('0', WCTYPE_XDIGIT), 0);
+ EXPECT_NE(iswctype('9', WCTYPE_XDIGIT), 0);
+ EXPECT_NE(iswctype('a', WCTYPE_XDIGIT), 0);
+ EXPECT_NE(iswctype('F', WCTYPE_XDIGIT), 0);
+ EXPECT_EQ(iswctype('g', WCTYPE_XDIGIT), 0);
+ EXPECT_EQ(iswctype('?', WCTYPE_XDIGIT), 0);
+
+ // invalid descriptor
+ EXPECT_EQ(iswctype('a', WCTYPE_INVALID), 0);
+ EXPECT_EQ(iswctype('a', static_cast<wctype_t>(999)), 0);
+}
diff --git a/libc/test/src/wctype/wctype_test.cpp b/libc/test/src/wctype/wctype_test.cpp
new file mode 100644
index 0000000000000..22a3f6d1e7e2e
--- /dev/null
+++ b/libc/test/src/wctype/wctype_test.cpp
@@ -0,0 +1,63 @@
+//===-- Unittests for wctype --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wctype/wctype.h"
+
+#include "test/UnitTest/Test.h"
+
+// wctype descriptors (must match implementation)
+static constexpr wctype_t WCTYPE_INVALID = static_cast<wctype_t>(0);
+static constexpr wctype_t WCTYPE_ALNUM = static_cast<wctype_t>(1);
+static constexpr wctype_t WCTYPE_ALPHA = static_cast<wctype_t>(2);
+static constexpr wctype_t WCTYPE_BLANK = static_cast<wctype_t>(3);
+static constexpr wctype_t WCTYPE_CNTRL = static_cast<wctype_t>(4);
+static constexpr wctype_t WCTYPE_DIGIT = static_cast<wctype_t>(5);
+static constexpr wctype_t WCTYPE_GRAPH = static_cast<wctype_t>(6);
+static constexpr wctype_t WCTYPE_LOWER = static_cast<wctype_t>(7);
+static constexpr wctype_t WCTYPE_PRINT = static_cast<wctype_t>(8);
+static constexpr wctype_t WCTYPE_PUNCT = static_cast<wctype_t>(9);
+static constexpr wctype_t WCTYPE_SPACE = static_cast<wctype_t>(10);
+static constexpr wctype_t WCTYPE_UPPER = static_cast<wctype_t>(11);
+static constexpr wctype_t WCTYPE_XDIGIT = static_cast<wctype_t>(12);
+
+TEST(LlvmLibcwctype, SimpleTest) {
+ using LIBC_NAMESPACE::wctype;
+
+ auto alnum = wctype("alnum");
+ auto alpha = wctype("alpha");
+ auto blank = wctype("blank");
+ auto cntrl = wctype("cntrl");
+ auto digit = wctype("digit");
+ auto graph = wctype("graph");
+ auto lower = wctype("lower");
+ auto print = wctype("print");
+ auto punct = wctype("punct");
+ auto space = wctype("space");
+ auto upper = wctype("upper");
+ auto xdigit = wctype("xdigit");
+
+ // valid descriptors should be nonzero
+ EXPECT_EQ(alnum, WCTYPE_ALNUM);
+ EXPECT_EQ(alpha, WCTYPE_ALPHA);
+ EXPECT_EQ(blank, WCTYPE_BLANK);
+ EXPECT_EQ(cntrl, WCTYPE_CNTRL);
+ EXPECT_EQ(digit, WCTYPE_DIGIT);
+ EXPECT_EQ(graph, WCTYPE_GRAPH);
+ EXPECT_EQ(lower, WCTYPE_LOWER);
+ EXPECT_EQ(print, WCTYPE_PRINT);
+ EXPECT_EQ(punct, WCTYPE_PUNCT);
+ EXPECT_EQ(space, WCTYPE_SPACE);
+ EXPECT_EQ(upper, WCTYPE_UPPER);
+ EXPECT_EQ(xdigit, WCTYPE_XDIGIT);
+
+ // invalid properties should return zero
+ EXPECT_EQ(wctype(""), WCTYPE_INVALID);
+ EXPECT_EQ(wctype("invalid"), WCTYPE_INVALID);
+ EXPECT_EQ(wctype("Alpha"), WCTYPE_INVALID);
+ EXPECT_EQ(wctype("unknown"), WCTYPE_INVALID);
+}
>From 4a5309eec8e00e58afa14b7450a6aede415a0d49 Mon Sep 17 00:00:00 2001
From: Zile Xiong <xiongzile99 at gmail.com>
Date: Fri, 10 Apr 2026 07:33:08 +0800
Subject: [PATCH 2/2] [libc] Add iswctype and wctype (v2)
- Change wctype_t from unsigned int to unsigned short
- Move iswctype and wctype out of the ascii namespace
- Use wctype_t instead of raw integer types in wctype_utils.h
- Introduce a mapping table to bind property names to descriptors
- Fix header formatting issues
---
libc/include/llvm-libc-types/wctype_t.h | 5 +-
libc/src/__support/wctype_utils.h | 222 ++++++++----------
libc/src/wctype/iswctype.cpp | 3 +-
libc/test/src/__support/wctype_utils_test.cpp | 17 +-
4 files changed, 113 insertions(+), 134 deletions(-)
diff --git a/libc/include/llvm-libc-types/wctype_t.h b/libc/include/llvm-libc-types/wctype_t.h
index b096c0061984a..e1d264b33150d 100644
--- a/libc/include/llvm-libc-types/wctype_t.h
+++ b/libc/include/llvm-libc-types/wctype_t.h
@@ -1,5 +1,4 @@
-//===-- Definition of wctype_t types
-//----------------------------------------===//
+//===-- Definition of wctype_t types --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,6 +9,6 @@
#ifndef LLVM_LIBC_TYPES_WCTYPE_T_H
#define LLVM_LIBC_TYPES_WCTYPE_T_H
-typedef unsigned int wctype_t;
+typedef unsigned short wctype_t;
#endif // LLVM_LIBC_TYPES_WCTYPE_T_H
diff --git a/libc/src/__support/wctype_utils.h b/libc/src/__support/wctype_utils.h
index e2b34e600f255..3ec8de098af21 100644
--- a/libc/src/__support/wctype_utils.h
+++ b/libc/src/__support/wctype_utils.h
@@ -10,6 +10,9 @@
#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
#include "hdr/types/wchar_t.h"
+#include "hdr/types/wctype_t.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
@@ -454,74 +457,6 @@ LIBC_INLINE constexpr wchar_t toupper(wchar_t wch) {
}
}
-LIBC_INLINE constexpr unsigned int wctype(const char *property) {
- if (!property)
- return 0; // WCTYPE_INVALID
-
- constexpr const char *names[] = {
- "unknown", // 0
- "alnum", // 1 - WCTYPE_ALNUM
- "alpha", // 2 - WCTYPE_ALPHA
- "blank", // 3 - WCTYPE_BLANK
- "cntrl", // 4 - WCTYPE_CNTRL
- "digit", // 5 - WCTYPE_DIGIT
- "graph", // 6 - WCTYPE_GRAPH
- "lower", // 7 - WCTYPE_LOWER
- "print", // 8 - WCTYPE_PRINT
- "punct", // 9 - WCTYPE_PUNCT
- "space", // 10 - WCTYPE_SPACE
- "upper", // 11 - WCTYPE_UPPER
- "xdigit" // 12 - WCTYPE_XDIGIT
- };
-
- for (unsigned int i = 1; i < sizeof(names) / sizeof(names[0]); ++i) {
- const char *s1 = property;
- const char *s2 = names[i];
-
- while (*s1 && (*s1 == *s2)) {
- ++s1;
- ++s2;
- }
-
- if (*s1 == *s2) {
- return i;
- }
- }
-
- return 0; // WCTYPE_INVALID
-}
-
-LIBC_INLINE constexpr int iswctype(wchar_t c, unsigned int desc) {
- switch (desc) {
- case 1:
- return isalnum(c); // alnum
- case 2:
- return isalpha(c); // alpha
- case 3:
- return isblank(c); // blank
- case 4:
- return iscntrl(c); // cntrl
- case 5:
- return isdigit(c); // digit
- case 6:
- return isgraph(c); // graph
- case 7:
- return islower(c); // lower
- case 8:
- return isprint(c); // print
- case 9:
- return ispunct(c); // punct
- case 10:
- return isspace(c); // space
- case 11:
- return isupper(c); // upper
- case 12:
- return isxdigit(c); // xdigit
- default:
- return 0;
- }
-}
-
} // namespace ascii
LIBC_INLINE constexpr bool islower(wchar_t wch) {
@@ -619,66 +554,6 @@ LIBC_INLINE constexpr bool isprint(wchar_t wch) {
return lookup_properties(wch) & PropertyFlag::PRINT;
#endif
}
-
-LIBC_INLINE constexpr bool iswctype(wchar_t wch, unsigned int desc) {
-#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
- return ascii::iswctype(wch, desc);
-#else
- if (static_cast<uint32_t>(wch) < 128) {
- return ascii::iswctype(wch, desc);
- }
-
- const unsigned prop = lookup_properties(wch);
-
- switch (desc) {
- case 1: // alnum
- return prop & PropertyFlag::ALPHA;
-
- case 2: // alpha
- return prop & PropertyFlag::ALPHA;
-
- case 3: // blank
- return prop & PropertyFlag::BLANK;
-
- case 4: // cntrl
- return prop & PropertyFlag::CNTRL;
-
- case 5: // digit
- return ascii::isdigit(wch);
-
- case 6: // graph
- // print && !space
- return (prop & (PropertyFlag::PRINT | PropertyFlag::SPACE)) ==
- PropertyFlag::PRINT;
-
- case 7: // lower
- return prop & PropertyFlag::LOWER;
-
- case 8: // print
- return prop & PropertyFlag::PRINT;
-
- case 9: // punct
- return prop & PropertyFlag::PUNCT;
-
- case 10: // space
- return prop & PropertyFlag::SPACE;
-
- case 11: // upper
- return prop & PropertyFlag::UPPER;
-
- case 12: // xdigit
- return ascii::isxdigit(wch);
-
- default:
- return false;
- }
-#endif
-}
-
-LIBC_INLINE constexpr unsigned int wctype(const char *property) {
- return ascii::wctype(property);
-}
-
LIBC_INLINE constexpr bool isxdigit(wchar_t wch) {
// Hexadecimal digits are the same in C.UTF8 as in ASCII
return ascii::isxdigit(wch);
@@ -706,6 +581,97 @@ LIBC_INLINE constexpr bool ispunct(wchar_t wch) {
#endif
}
+struct wctype_desc {
+#ifdef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
+ string_view name;
+#else
+ cpp::string_view name;
+#endif
+ wctype_t desc;
+};
+
+LIBC_INLINE constexpr wctype_t WCTYPE_INVALID = 0;
+LIBC_INLINE constexpr wctype_t WCTYPE_ALNUM = 1;
+LIBC_INLINE constexpr wctype_t WCTYPE_ALPHA = 2;
+LIBC_INLINE constexpr wctype_t WCTYPE_BLANK = 3;
+LIBC_INLINE constexpr wctype_t WCTYPE_CNTRL = 4;
+LIBC_INLINE constexpr wctype_t WCTYPE_DIGIT = 5;
+LIBC_INLINE constexpr wctype_t WCTYPE_GRAPH = 6;
+LIBC_INLINE constexpr wctype_t WCTYPE_LOWER = 7;
+LIBC_INLINE constexpr wctype_t WCTYPE_PRINT = 8;
+LIBC_INLINE constexpr wctype_t WCTYPE_PUNCT = 9;
+LIBC_INLINE constexpr wctype_t WCTYPE_SPACE = 10;
+LIBC_INLINE constexpr wctype_t WCTYPE_UPPER = 11;
+LIBC_INLINE constexpr wctype_t WCTYPE_XDIGIT = 12;
+
+#ifdef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
+array<wctype_desc, 12> mappings = {{
+#else
+cpp::array<wctype_desc, 12> mappings = {{
+#endif
+ {"alnum", WCTYPE_ALNUM},
+ {"alpha", WCTYPE_ALPHA},
+ {"blank", WCTYPE_BLANK},
+ {"cntrl", WCTYPE_CNTRL},
+ {"digit", WCTYPE_DIGIT},
+ {"graph", WCTYPE_GRAPH},
+ {"lower", WCTYPE_LOWER},
+ {"print", WCTYPE_PRINT},
+ {"punct", WCTYPE_PUNCT},
+ {"space", WCTYPE_SPACE},
+ {"upper", WCTYPE_UPPER},
+ {"xdigit", WCTYPE_XDIGIT},
+}};
+
+LIBC_INLINE constexpr wctype_t wctype(const char *property) {
+ if (!property)
+ return WCTYPE_INVALID;
+
+#ifdef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
+ string_view pro(property);
+#else
+ cpp::string_view pro(property);
+#endif
+
+ for (const auto &wc : mappings) {
+ if (wc.name.compare(pro) == 0) {
+ return wc.desc;
+ }
+ }
+ return 0; // WCTYPE_INVALID
+}
+
+LIBC_INLINE constexpr int iswctype(wchar_t c, wctype_t desc) {
+ switch (desc) {
+ case WCTYPE_ALNUM:
+ return isalnum(c);
+ case WCTYPE_ALPHA:
+ return isalpha(c);
+ case WCTYPE_BLANK:
+ return isblank(c);
+ case WCTYPE_CNTRL:
+ return iscntrl(c);
+ case WCTYPE_DIGIT:
+ return isdigit(c);
+ case WCTYPE_GRAPH:
+ return isgraph(c);
+ case WCTYPE_LOWER:
+ return islower(c);
+ case WCTYPE_PRINT:
+ return isprint(c);
+ case WCTYPE_PUNCT:
+ return ispunct(c);
+ case WCTYPE_SPACE:
+ return isspace(c);
+ case WCTYPE_UPPER:
+ return isupper(c);
+ case WCTYPE_XDIGIT:
+ return isxdigit(c);
+ default:
+ return 0;
+ }
+}
+
LIBC_INLINE constexpr wchar_t tolower(wchar_t wch) {
#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
return ascii::tolower(wch);
diff --git a/libc/src/wctype/iswctype.cpp b/libc/src/wctype/iswctype.cpp
index 87bf0e31fe463..1604836225fee 100644
--- a/libc/src/wctype/iswctype.cpp
+++ b/libc/src/wctype/iswctype.cpp
@@ -16,8 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, iswctype, (wint_t c, wctype_t desc)) {
- return internal::iswctype(static_cast<wchar_t>(c),
- static_cast<unsigned int>(desc));
+ return internal::iswctype(static_cast<wchar_t>(c), desc);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/__support/wctype_utils_test.cpp b/libc/test/src/__support/wctype_utils_test.cpp
index 9bc7e818cdbc6..0175d183b2c22 100644
--- a/libc/test/src/__support/wctype_utils_test.cpp
+++ b/libc/test/src/__support/wctype_utils_test.cpp
@@ -1,7 +1,9 @@
+#include "hdr/types/wctype_t.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/CPP/string_view.h"
#include "src/__support/macros/config.h"
#include "src/__support/wctype/wctype_classification_utils.h"
#include "test/UnitTest/Test.h"
-
namespace {
namespace ascii_mode {
@@ -9,7 +11,15 @@ namespace ascii_mode {
#define LIBC_CONF_WCTYPE_MODE LIBC_WCTYPE_MODE_ASCII
#undef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
+
+namespace LIBC_NAMESPACE_DECL {
+using ::LIBC_NAMESPACE::cpp::array;
+using ::LIBC_NAMESPACE::cpp::string_view;
+} // namespace LIBC_NAMESPACE_DECL
+#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
#include "src/__support/wctype_utils.h"
+#undef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
+
} // namespace ascii_mode
namespace utf8_mode {
@@ -19,10 +29,15 @@ namespace utf8_mode {
namespace LIBC_NAMESPACE_DECL {
using ::LIBC_NAMESPACE::lookup_properties;
using ::LIBC_NAMESPACE::PropertyFlag;
+using ::LIBC_NAMESPACE::cpp::array;
+using ::LIBC_NAMESPACE::cpp::string_view;
} // namespace LIBC_NAMESPACE_DECL
#undef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_H
+
+#define LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
#include "src/__support/wctype_utils.h"
+#undef LLVM_LIBC_SRC___SUPPORT_WCTYPE_UTILS_TEST
} // namespace utf8_mode
struct TestCase {
More information about the libc-commits
mailing list