Skip to content

Commit 1a18767

Browse files
authored
[libc++] Use proper functions instead of macros in bsd_locale_defaults.h (#113759)
We were using macros instead of functions, leading to the inability to properly qualify calls to those symbols inside <locale>. This is also a step towards making the locale API modules-correct.
1 parent cd340a4 commit 1a18767

File tree

5 files changed

+116
-28
lines changed

5 files changed

+116
-28
lines changed

libcxx/include/__locale_dir/locale_base_api.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
1010
#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
1111

12+
#include <__config>
13+
1214
#if defined(_LIBCPP_MSVCRT_LIKE)
1315
# include <__locale_dir/locale_base_api/win32.h>
1416
#elif defined(_AIX) || defined(__MVS__)
@@ -27,6 +29,12 @@
2729
# include <__locale_dir/locale_base_api/freebsd.h>
2830
#endif
2931

32+
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
33+
# include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
34+
#else
35+
# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
36+
#endif
37+
3038
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3139
# pragma GCC system_header
3240
#endif
@@ -46,7 +54,8 @@ size_t __libcpp_mbsnrtowcs_l(wchar_t* dest, const char** src, size_t max_out, si
4654
size_t __libcpp_mbrtowc_l(wchar_t* dest, cosnt char* src, size_t count, mbstate_t*, locale_t);
4755
int __libcpp_mbtowc_l(wchar_t* dest, const char* src, size_t count, locale_t);
4856
size_t __libcpp_mbrlen_l(const char* str, size_t count, mbstate_t*, locale_t);
49-
lconv* __libcpp_localeconv_l(locale_t);
57+
// TODO: __libcpp_localeconv_l shouldn't take a reference, but the Windows implementation doesn't allow copying locale_t
58+
lconv* __libcpp_localeconv_l(locale_t&);
5059
size_t __libcpp_mbsrtowcs_l(wchar_t* dest, const char** src, size_t len, mbstate_t*, locale_t);
5160
int __libcpp_snprintf_l(char* dest, size_t buff_size, locale_t, const char* format, ...);
5261
int __libcpp_asprintf_l(char** dest, locale_t, const char* format, ...);

libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h

+93-14
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,102 @@
1414
#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
1515
#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H
1616

17+
#include <ctype.h>
18+
#include <stdio.h>
19+
#include <stdlib.h>
20+
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
21+
# include <wchar.h>
22+
#endif
23+
24+
// <xlocale.h> must come after the includes above since the functions it includes depend on
25+
// what headers have been included up to that point.
26+
#if defined(__APPLE__) || defined(__FreeBSD__)
27+
# include <xlocale.h>
28+
#endif
29+
30+
#include <__config>
31+
#include <__cstddef/size_t.h>
32+
#include <__std_mbstate_t.h>
33+
#include <__utility/forward.h>
34+
1735
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1836
# pragma GCC system_header
1937
#endif
2038

21-
#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc)
22-
#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc)
23-
#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc)
24-
#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc)
25-
#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc)
26-
#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc)
27-
#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l)
28-
#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l)
29-
#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l)
30-
#define __libcpp_localeconv_l(l) localeconv_l(l)
31-
#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l)
32-
#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__)
33-
#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__)
34-
#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__)
39+
_LIBCPP_BEGIN_NAMESPACE_STD
40+
41+
inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __loc) { return MB_CUR_MAX_L(__loc); }
42+
43+
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
44+
inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_btowc_l(int __c, locale_t __loc) { return ::btowc_l(__c, __loc); }
45+
46+
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_wctob_l(wint_t __c, locale_t __loc) { return ::wctob_l(__c, __loc); }
47+
48+
inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcsnrtombs_l(
49+
char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, locale_t __loc) {
50+
return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
51+
}
52+
53+
inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcrtomb_l(char* __s, wchar_t __wc, mbstate_t* __ps, locale_t __loc) {
54+
return ::wcrtomb_l(__s, __wc, __ps, __loc);
55+
}
56+
57+
inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbsnrtowcs_l(
58+
wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, locale_t __loc) {
59+
return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
60+
}
61+
62+
inline _LIBCPP_HIDE_FROM_ABI size_t
63+
__libcpp_mbrtowc_l(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
64+
return ::mbrtowc_l(__pwc, __s, __n, __ps, __loc);
65+
}
66+
67+
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mbtowc_l(wchar_t* __pwc, const char* __pmb, size_t __max, locale_t __loc) {
68+
return ::mbtowc_l(__pwc, __pmb, __max, __loc);
69+
}
70+
71+
inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) {
72+
return ::mbrlen_l(__s, __n, __ps, __loc);
73+
}
74+
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
75+
76+
inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t& __loc) { return ::localeconv_l(__loc); }
77+
78+
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
79+
inline _LIBCPP_HIDE_FROM_ABI size_t
80+
__libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, locale_t __loc) {
81+
return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
82+
}
83+
#endif
84+
85+
_LIBCPP_DIAGNOSTIC_PUSH
86+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")
87+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates
88+
#ifdef _LIBCPP_COMPILER_CLANG_BASED
89+
# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__)
90+
#else
91+
# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT
92+
#endif
93+
94+
template <class... _Args>
95+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l(
96+
char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) {
97+
return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...);
98+
}
99+
100+
template <class... _Args>
101+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l(
102+
char** __s, locale_t __loc, const char* __format, _Args&&... __args) {
103+
return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
104+
}
105+
106+
template <class... _Args>
107+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l(
108+
const char* __s, locale_t __loc, const char* __format, _Args&&... __args) {
109+
return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
110+
}
111+
_LIBCPP_DIAGNOSTIC_POP
112+
113+
_LIBCPP_END_NAMESPACE_STD
35114

36115
#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H

libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
1414
#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H
1515

16+
#include <locale.h>
17+
1618
#include <__locale_dir/locale_guard.h>
17-
#include <cstdio>
1819
#include <stdarg.h>
20+
#include <stdio.h>
1921
#include <stdlib.h>
2022

2123
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -78,7 +80,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __
7880
}
7981
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
8082

81-
inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __l) {
83+
inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t& __l) {
8284
__locale_guard __current(__l);
8385
return localeconv();
8486
}

libcxx/include/locale

+1-11
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ template <class charT> class messages_byname;
215215
# include <streambuf>
216216
# include <version>
217217

218-
// TODO: Fix __bsd_locale_defaults.h
218+
// TODO: Properly qualify calls now that __bsd_locale_defaults.h defines functions instead of macros
219219
// NOLINTBEGIN(libcpp-robust-against-adl)
220220

221221
# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
@@ -230,16 +230,6 @@ template <class charT> class messages_byname;
230230
# define _LIBCPP_HAS_CATOPEN 0
231231
# endif
232232

233-
# ifdef _LIBCPP_LOCALE__L_EXTENSIONS
234-
# include <__locale_dir/locale_base_api/bsd_locale_defaults.h>
235-
# else
236-
# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
237-
# endif
238-
239-
# if defined(__APPLE__) || defined(__FreeBSD__)
240-
# include <xlocale.h>
241-
# endif
242-
243233
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
244234
# pragma GCC system_header
245235
# endif

libcxx/test/libcxx/clang_modules_include.gen.py

+8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
//--- {header}.compile.pass.cpp
3030
// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only
3131
32+
// Older macOS SDKs were not properly modularized, which causes issues with localization.
33+
// This feature should instead be based on the SDK version.
34+
// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
35+
3236
// GCC doesn't support -fcxx-modules
3337
// UNSUPPORTED: gcc
3438
@@ -59,6 +63,10 @@
5963
6064
// REQUIRES: clang-modules-build
6165
66+
// Older macOS SDKs were not properly modularized, which causes issues with localization.
67+
// This feature should instead be based on the SDK version.
68+
// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}}
69+
6270
// GCC doesn't support -fcxx-modules
6371
// UNSUPPORTED: gcc
6472

0 commit comments

Comments
 (0)