Skip to content

Conversation

zibi2
Copy link
Contributor

@zibi2 zibi2 commented Dec 9, 2024

This PR is necessary to resolve name collisions between locale functions defined within libc++ and macros used in z/OS system header, locale.h. Those macros cannot be changed since they are visible and out in the field for many releases.

In addition, the zos wrapper locale.h header is created to remove conflict between __locale namespace and guard macro used by z/OS system header. This change is temporary until system header is altered to do the same.

The PR is to address build issues on z/OS caused by PR 114596.
The following is a sample of errors:

.../include/c++/v1/__locale_dir/locale_base_api.h:181:54: error: too many arguments provided to function-like macro invocation
  181 | inline _LIBCPP_HIDE_FROM_ABI int __islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); }
      |                                                      ^
...util/usr/include/ctype.h:387:11: note: macro '__islower' defined here
  387 |   #define __islower(c) (_TYPCHK((c),__ISLOWER))
      |           ^

@zibi2 zibi2 self-assigned this Dec 9, 2024
@zibi2 zibi2 requested a review from a team as a code owner December 9, 2024 18:17
@llvmbot llvmbot added clang Clang issues not falling into any other category libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. backend:X86 clang:headers Headers provided by Clang, e.g. for intrinsics labels Dec 9, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2024

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-libcxx

@llvm/pr-subscribers-clang

Author: Zibi Sarbinowski (zibi2)

Changes

This PR is necessary to resolve name collisions between locale functions defined within libc++ and macros used in z/OS system header, locale.h. Those macros cannot be changed since they are visible and out in the field for many releases.

In addition, the zos wrapper locale.h header is created to remove conflict between __locale namespace and guard macro used by z/OS system header. This change is temporary until system header is altered to do the same.

The PR is to address build issues on z/OS caused by PR 114596.
The following is a sample of errors:

.../include/c++/v1/__locale_dir/locale_base_api.h:181:54: error: too many arguments provided to function-like macro invocation
  181 | inline _LIBCPP_HIDE_FROM_ABI int __islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); }
      |                                                      ^
...util/usr/include/ctype.h:387:11: note: macro '__islower' defined here
  387 |   #define __islower(c) (_TYPCHK((c),__ISLOWER))
      |           ^

Patch is 31.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119241.diff

6 Files Affected:

  • (modified) clang/lib/Headers/CMakeLists.txt (+1)
  • (added) clang/lib/Headers/zos_wrappers/locale.h (+19)
  • (modified) libcxx/include/__locale_dir/locale_base_api.h (+61-58)
  • (modified) libcxx/include/__locale_dir/locale_base_api/ibm.h (+33)
  • (modified) libcxx/include/locale (+2-2)
  • (modified) libcxx/src/locale.cpp (+70-70)
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 43124111b7ba5a..71f2ff268548d5 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -381,6 +381,7 @@ set(llvm_libc_wrapper_files
 
 set(zos_wrapper_files
   zos_wrappers/builtins.h
+  zos_wrappers/locale.h
 )
 
 include(GetClangResourceDir)
diff --git a/clang/lib/Headers/zos_wrappers/locale.h b/clang/lib/Headers/zos_wrappers/locale.h
new file mode 100644
index 00000000000000..1381f6d47ac097
--- /dev/null
+++ b/clang/lib/Headers/zos_wrappers/locale.h
@@ -0,0 +1,19 @@
+/*===----------------------------- locale.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 __ZOS_WRAPPERS_LOCALE_H
+#define __ZOS_WRAPPERS_LOCALE_H
+  #if defined(__MVS__)
+    #include_next <locale.h>
+    #ifdef __locale
+      #undef __locale
+      #define __locale __locale
+    #endif
+  #endif /* defined(__MVS__) */
+#endif /* __ZOS_WRAPPERS_LOCALE_H */
diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 8ed4c29cb8732f..9bd3420b65fcf8 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -39,41 +39,41 @@
 // Strtonum functions
 // ------------------
 // namespace __locale {
-//  float               __strtof(const char*, char**, __locale_t);
-//  double              __strtod(const char*, char**, __locale_t);
-//  long double         __strtold(const char*, char**, __locale_t);
-//  long long           __strtoll(const char*, char**, __locale_t);
-//  unsigned long long  __strtoull(const char*, char**, __locale_t);
+//  float               __libcpp_strtof(const char*, char**, __locale_t);
+//  double              __libcpp_strtod(const char*, char**, __locale_t);
+//  long double         __libcpp_strtold(const char*, char**, __locale_t);
+//  long long           __libcpp_strtoll(const char*, char**, __locale_t);
+//  unsigned long long  __libcpp_strtoull(const char*, char**, __locale_t);
 // }
 //
 // Character manipulation functions
 // --------------------------------
 // namespace __locale {
-//  int     __islower(int, __locale_t);
-//  int     __isupper(int, __locale_t);
-//  int     __isdigit(int, __locale_t);
-//  int     __isxdigit(int, __locale_t);
-//  int     __toupper(int, __locale_t);
-//  int     __tolower(int, __locale_t);
-//  int     __strcoll(const char*, const char*, __locale_t);
-//  size_t  __strxfrm(char*, const char*, size_t, __locale_t);
+//  int     __libcpp_islower(int, __locale_t);
+//  int     __libcpp_isupper(int, __locale_t);
+//  int     __libcpp_isdigit(int, __locale_t);
+//  int     __libcpp_isxdigit(int, __locale_t);
+//  int     __libcpp_toupper(int, __locale_t);
+//  int     __libcpp_tolower(int, __locale_t);
+//  int     __libcpp_strcoll(const char*, const char*, __locale_t);
+//  size_t  __libcpp_strxfrm(char*, const char*, size_t, __locale_t);
 //
-//  int     __iswspace(wint_t, __locale_t);
-//  int     __iswprint(wint_t, __locale_t);
-//  int     __iswcntrl(wint_t, __locale_t);
-//  int     __iswupper(wint_t, __locale_t);
-//  int     __iswlower(wint_t, __locale_t);
-//  int     __iswalpha(wint_t, __locale_t);
-//  int     __iswblank(wint_t, __locale_t);
-//  int     __iswdigit(wint_t, __locale_t);
-//  int     __iswpunct(wint_t, __locale_t);
-//  int     __iswxdigit(wint_t, __locale_t);
-//  wint_t  __towupper(wint_t, __locale_t);
-//  wint_t  __towlower(wint_t, __locale_t);
-//  int     __wcscoll(const wchar_t*, const wchar_t*, __locale_t);
-//  size_t  __wcsxfrm(wchar_t*, const wchar_t*, size_t, __locale_t);
+//  int     __libcpp_iswspace(wint_t, __locale_t);
+//  int     __libcpp_iswprint(wint_t, __locale_t);
+//  int     __libcpp_iswcntrl(wint_t, __locale_t);
+//  int     __libcpp_iswupper(wint_t, __locale_t);
+//  int     __libcpp_iswlower(wint_t, __locale_t);
+//  int     __libcpp_iswalpha(wint_t, __locale_t);
+//  int     __libcpp_iswblank(wint_t, __locale_t);
+//  int     __libcpp_iswdigit(wint_t, __locale_t);
+//  int     __libcpp_iswpunct(wint_t, __locale_t);
+//  int     __libcpp_iswxdigit(wint_t, __locale_t);
+//  wint_t  __libcpp_towupper(wint_t, __locale_t);
+//  wint_t  __libcpp_towlower(wint_t, __locale_t);
+//  int     __libcpp_wcscoll(const wchar_t*, const wchar_t*, __locale_t);
+//  size_t  __libcpp_wcsxfrm(wchar_t*, const wchar_t*, size_t, __locale_t);
 //
-//  size_t  __strftime(char*, size_t, const char*, const tm*, __locale_t);
+//  size_t  __libcpp_strftime(char*, size_t, const char*, const tm*, __locale_t);
 // }
 //
 // Other functions
@@ -154,68 +154,71 @@ inline _LIBCPP_HIDE_FROM_ABI lconv* __localeconv(__locale_t& __loc) { return __l
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI float __libcpp_strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
   return strtof_l(__nptr, __endptr, __loc);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI double __libcpp_strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
   return strtod_l(__nptr, __endptr, __loc);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI long double __libcpp_strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
   return strtold_l(__nptr, __endptr, __loc);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI long long __libcpp_strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
   return strtoll_l(__nptr, __endptr, __base, __loc);
 }
 
 inline _LIBCPP_HIDE_FROM_ABI unsigned long long
-__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
+__libcpp_strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
   return strtoull_l(__nptr, __endptr, __base, __loc);
 }
 
+#    if defined(__MVS__)
+using namespace __ibm;
+#    endif
+
 //
 // Character manipulation functions
 //
-inline _LIBCPP_HIDE_FROM_ABI int __islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __ch, __locale_t __loc) { return isupper_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_isupper(int __ch, __locale_t __loc) { return isupper_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
   return strcoll_l(__s1, __s2, __loc);
 }
-inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) {
   return strxfrm_l(__dest, __src, __n, __loc);
 }
-inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __ch, __locale_t __loc) { return toupper_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __ch, __locale_t __loc) { return tolower_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_toupper(int __ch, __locale_t __loc) { return toupper_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tolower(int __ch, __locale_t __loc) { return tolower_l(__ch, __loc); }
 
 #  if _LIBCPP_HAS_WIDE_CHARACTERS
-inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __s1, const wchar_t* __s2, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_wcscoll(const wchar_t* __s1, const wchar_t* __s2, __locale_t __loc) {
   return wcscoll_l(__s1, __s2, __loc);
 }
-inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
+inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
   return wcsxfrm_l(__dest, __src, __n, __loc);
 }
-inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __ch, __locale_t __loc) { return iswspace_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __ch, __locale_t __loc) { return iswprint_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __ch, __locale_t __loc) { return iswcntrl_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __ch, __locale_t __loc) { return iswupper_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __ch, __locale_t __loc) { return iswlower_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __ch, __locale_t __loc) { return iswalpha_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __ch, __locale_t __loc) { return iswblank_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __ch, __locale_t __loc) { return iswdigit_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __ch, __locale_t __loc) { return iswpunct_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __ch, __locale_t __loc) { return iswxdigit_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __ch, __locale_t __loc) { return towupper_l(__ch, __loc); }
-inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __ch, __locale_t __loc) { return towlower_l(__ch, __loc); }
-#  endif
-
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswspace(wint_t __ch, __locale_t __loc) { return iswspace_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswprint(wint_t __ch, __locale_t __loc) { return iswprint_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswcntrl(wint_t __ch, __locale_t __loc) { return iswcntrl_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswupper(wint_t __ch, __locale_t __loc) { return iswupper_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswlower(wint_t __ch, __locale_t __loc) { return iswlower_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswalpha(wint_t __ch, __locale_t __loc) { return iswalpha_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswblank(wint_t __ch, __locale_t __loc) { return iswblank_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswdigit(wint_t __ch, __locale_t __loc) { return iswdigit_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswpunct(wint_t __ch, __locale_t __loc) { return iswpunct_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI int __libcpp_iswxdigit(wint_t __ch, __locale_t __loc) { return iswxdigit_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_towupper(wint_t __ch, __locale_t __loc) { return towupper_l(__ch, __loc); }
+inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_towlower(wint_t __ch, __locale_t __loc) { return towlower_l(__ch, __loc); }
 inline _LIBCPP_HIDE_FROM_ABI size_t
-__strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __locale_t __loc) {
+__libcpp_strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __locale_t __loc) {
   return strftime_l(__s, __max, __format, __tm, __loc);
 }
+#  endif
 
 //
 // Other functions
diff --git a/libcxx/include/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__locale_dir/locale_base_api/ibm.h
index 1d1d15df9f7995..4d4b1e3d38fd2f 100644
--- a/libcxx/include/__locale_dir/locale_base_api/ibm.h
+++ b/libcxx/include/__locale_dir/locale_base_api/ibm.h
@@ -105,4 +105,37 @@ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char
   return str_size;
 }
 
+namespace __ibm {
+_LIBCPP_EXPORTED_FROM_ABI int isalnum_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isalpha_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isblank_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iscntrl_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isgraph_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int islower_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isprint_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int ispunct_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isspace_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int isupper_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswalnum_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswalpha_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswblank_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswcntrl_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswdigit_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswgraph_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswlower_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswprint_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswpunct_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswspace_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswupper_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int iswxdigit_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int toupper_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int tolower_l(int, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI wint_t towupper_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI wint_t towlower_l(wint_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int strcoll_l(const char *, const char *, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI size_t strxfrm_l(char *, const char *, size_t, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI size_t strftime_l(char *, size_t , const char *, const struct tm *, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
+_LIBCPP_EXPORTED_FROM_ABI size_t wcsxfrm_l(wchar_t *, const wchar_t *, size_t , locale_t);
+}
 #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_IBM_H
diff --git a/libcxx/include/locale b/libcxx/include/locale
index aa6733427d2d08..937c872c9506f9 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -1126,11 +1126,11 @@ void __num_put<_CharT>::__widen_and_group_float(
     *__oe++ = __ct.widen(*__nf++);
     *__oe++ = __ct.widen(*__nf++);
     for (__ns = __nf; __ns < __ne; ++__ns)
-      if (!__locale::__isxdigit(*__ns, _LIBCPP_GET_C_LOCALE))
+      if (!__locale::__libcpp_isxdigit(*__ns, _LIBCPP_GET_C_LOCALE))
         break;
   } else {
     for (__ns = __nf; __ns < __ne; ++__ns)
-      if (!__locale::__isdigit(*__ns, _LIBCPP_GET_C_LOCALE))
+      if (!__locale::__libcpp_isdigit(*__ns, _LIBCPP_GET_C_LOCALE))
         break;
   }
   if (__grouping.empty()) {
diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index a1e10401f0b299..135ff55e9ad031 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -625,7 +625,7 @@ int collate_byname<char>::do_compare(
     const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {
   string_type lhs(__lo1, __hi1);
   string_type rhs(__lo2, __hi2);
-  int r = __locale::__strcoll(lhs.c_str(), rhs.c_str(), __l_);
+  int r = __locale::__libcpp_strcoll(lhs.c_str(), rhs.c_str(), __l_);
   if (r < 0)
     return -1;
   if (r > 0)
@@ -635,8 +635,8 @@ int collate_byname<char>::do_compare(
 
 collate_byname<char>::string_type collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const {
   const string_type in(lo, hi);
-  string_type out(__locale::__strxfrm(0, in.c_str(), 0, __l_), char());
-  __locale::__strxfrm(const_cast<char*>(out.c_str()), in.c_str(), out.size() + 1, __l_);
+  string_type out(__locale::__libcpp_strxfrm(0, in.c_str(), 0, __l_), char());
+  __locale::__libcpp_strxfrm(const_cast<char*>(out.c_str()), in.c_str(), out.size() + 1, __l_);
   return out;
 }
 
@@ -669,7 +669,7 @@ int collate_byname<wchar_t>::do_compare(
     const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {
   string_type lhs(__lo1, __hi1);
   string_type rhs(__lo2, __hi2);
-  int r = __locale::__wcscoll(lhs.c_str(), rhs.c_str(), __l_);
+  int r = __locale::__libcpp_wcscoll(lhs.c_str(), rhs.c_str(), __l_);
   if (r < 0)
     return -1;
   if (r > 0)
@@ -680,8 +680,8 @@ int collate_byname<wchar_t>::do_compare(
 collate_byname<wchar_t>::string_type
 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const {
   const string_type in(lo, hi);
-  string_type out(__locale::__wcsxfrm(0, in.c_str(), 0, __l_), wchar_t());
-  __locale::__wcsxfrm(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size() + 1, __l_);
+  string_type out(__locale::__libcpp_wcsxfrm(0, in.c_str(), 0, __l_), wchar_t());
+  __locale::__libcpp_wcsxfrm(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size() + 1, __l_);
   return out;
 }
 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
@@ -736,7 +736,7 @@ wchar_t ctype<wchar_t>::do_toupper(char_type c) const {
 #  elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__MVS__)
   return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
 #  else
-  return (isascii(c) && __locale::__iswlower(c, _LIBCPP_GET_C_LOCALE)) ? c - L'a' + L'A' : c;
+  return (isascii(c) && __locale::__libcpp_iswlower(c, _LIBCPP_GET_C_LOCALE)) ? c - L'a' + L'A' : c;
 #  endif
 }
 
@@ -1064,22 +1064,22 @@ ctype_byname<char>::ctype_byname(const string& name, size_t refs)
 ctype_byname<char>::~ctype_byname() { __locale::__freelocale(__l_); }
 
 char ctype_byname<char>::do_toupper(char_type c) const {
-  return static_cast<char>(__locale::__toupper(static_cast<unsigned char>(c), __l_));
+  return static_cast<char>(__locale::__libcpp_toupper(static_cast<unsigned char>(c), __l_));
 }
 
 const char* ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const {
   for (; low != high; ++low)
-    *low = static_cast<char>(__locale::__toupper(static_cast<unsigned char>(*low), __l_));
+    *low = static_cast<char>(__locale::__libcpp_toupper(static_cast<unsigned char>(*low), __l_));
   return low;
 }
 
 char ctype_byname<char>::do_tolower(char_type c) const {
-  return static_cast<char>(__locale::__tolower(static_cast<unsigned char>(c), __l_));
+  return static_cast<char>(__locale::__libcpp_tolower(static_cast<unsigned char>(c), __l_));
 }
 
 const char* ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const {
   for (; low != high; ++low)
-    *low = static_cast<char>(__locale::__tolower(static_cast<unsigned char>(*low), __l_));
+    *low = static_cast<char>(__locale::__libcpp_tolower(static_cast<unsigned char>(*low), __l_));
   return low;
 }
 
@@ -1115,25 +1115,25 @@ bool ctype_byname<wchar_t>::do_is(mask m, char_type c) const {
   bool result = false;
   wint_t ch   = static_cast<wint_t>(c);
   if ((m & space) == space)
-    result |= (__locale::__iswspace(ch, __l_) != 0);
+    result |= (__locale__libcpp_iswspace(ch, __l_) != 0);
   if ((m & print) == print)
-    result |= (__locale::__iswprint(ch, __l_) != 0);
+    result |= (__locale::__libcpp_iswprint(ch, __l_) != 0);
   if ((m & cntrl) == cntrl)
-    result |= (__locale::__iswcntrl(ch, __l_) != 0);
+    result |= (__locale::__libcpp_iswcntrl(ch, __l_) != 0);
   if ((m & upper) == upper)
-    result |= (__locale::__iswupper(ch, __l_) != 0);
+    result |= (__locale::__libcpp_iswupper(ch, __l_) != 0);
   if ((m & lower) == lower)
-    result |= (__locale::__iswlower(ch, __l_) != 0);
+    result |= (__locale::__libcpp_iswlower(ch, __l_) != 0);
   if ((m & alpha) == alpha)
-    result |= (__locale::__iswalpha(ch, __l_) != 0);
+    result |= (__locale::__libcpp_iswalpha(ch, __l_) != 0);
   if ((m & digit) == digit)
-    result |= (__locale::__iswdigit(ch, __l_) != 0);
+    result |= (__locale::__libcpp_iswdigit(ch, __l_) != 0);
   if ((m & punct) == punct)
-    result |= (__l...
[truncated]

…te name collition with macors in system locale.h header
Copy link

github-actions bot commented Dec 9, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, can't you #undef these macros? We're trying to move away from defining names with __libcpp.

@perry-ca
Copy link
Contributor

perry-ca commented Dec 9, 2024

These macros can't be undef'ed as they are used to implement the functions like islower(int) by the headers like ctype.h. Any name other than __X will work for these inline functions in libc++.

@zibi2
Copy link
Contributor Author

zibi2 commented Jan 28, 2025

Louis, are you still in position of not accepting the rename proposal in this PR?

I was able to resolve the __locale_t name collision with a wrapper, but unfortunately, as Sean pointed out, we cannot undefine other macros conflicting with the inline functions in libc++. If we cannot use the __libcpp_ prefix anymore, what is the recommended way of resolving name collisions? When the use of the __libcpp_ prefix was discouraged, was there any alternative for resolving name collisions with the underlying system C library?

@zibi2 zibi2 requested a review from ldionne January 28, 2025 20:30
@ldionne
Copy link
Member

ldionne commented Jan 28, 2025

Which identifiers exactly are causing issues? I think we could tackle that by adding them to __undef_macros and to _LIBCPP_PUSH_MACROS and _LIBCPP_POP_MACROS instead. That's generally what we do to work around name collisions on individual platforms: it's more robust and doesn't require changing libc++'s source code due to name conflicts, which could be arbitrary (in principle, a platform could also be defining __libcpp_strtof, so the only bulletproof way of addressing this issue is push/pop).

@zibi2
Copy link
Contributor Author

zibi2 commented Jan 28, 2025

... the only bulletproof way of addressing this issue is push/pop

Thx, I will experiment with push/pop and handle only names we have in conflict.

@ldionne
Copy link
Member

ldionne commented Jan 30, 2025

Closing in the meantime, please reopen this PR or create a new one with the new approach whenever you're ready!

@ldionne ldionne closed this Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 clang:headers Headers provided by Clang, e.g. for intrinsics clang Clang issues not falling into any other category libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants