Skip to content

Commit f00b32e

Browse files
authored
[libc++] Reduce the dependency of the locale base API on the base system from the headers (llvm#117764)
Many parts of the locale base API are only required when building the shared/static library, but not from the headers. Document those functions and carve out a few of those that don't work when _XOPEN_SOURCE is defined to something old. Fixes llvm#117630
1 parent 8feb5ba commit f00b32e

File tree

6 files changed

+128
-38
lines changed

6 files changed

+128
-38
lines changed

libcxx/include/__locale_dir/locale_base_api.h

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,24 @@
2323
// Variadic functions may be implemented as templates with a parameter pack instead
2424
// of C-style variadic functions.
2525
//
26+
// Most of these functions are only required when building the library. Functions that are also
27+
// required when merely using the headers are marked as such below.
28+
//
2629
// TODO: __localeconv shouldn't take a reference, but the Windows implementation doesn't allow copying __locale_t
30+
// TODO: Eliminate the need for any of these functions from the headers.
2731
//
2832
// Locale management
2933
// -----------------
3034
// namespace __locale {
31-
// using __locale_t = implementation-defined;
35+
// using __locale_t = implementation-defined; // required by the headers
3236
// using __lconv_t = implementation-defined;
3337
// __locale_t __newlocale(int, const char*, __locale_t);
3438
// void __freelocale(__locale_t);
3539
// char* __setlocale(int, const char*);
3640
// __lconv_t* __localeconv(__locale_t&);
3741
// }
3842
//
43+
// // required by the headers
3944
// #define _LIBCPP_COLLATE_MASK /* implementation-defined */
4045
// #define _LIBCPP_CTYPE_MASK /* implementation-defined */
4146
// #define _LIBCPP_MONETARY_MASK /* implementation-defined */
@@ -48,6 +53,7 @@
4853
// Strtonum functions
4954
// ------------------
5055
// namespace __locale {
56+
// // required by the headers
5157
// float __strtof(const char*, char**, __locale_t);
5258
// double __strtod(const char*, char**, __locale_t);
5359
// long double __strtold(const char*, char**, __locale_t);
@@ -60,8 +66,8 @@
6066
// namespace __locale {
6167
// int __islower(int, __locale_t);
6268
// int __isupper(int, __locale_t);
63-
// int __isdigit(int, __locale_t);
64-
// int __isxdigit(int, __locale_t);
69+
// int __isdigit(int, __locale_t); // required by the headers
70+
// int __isxdigit(int, __locale_t); // required by the headers
6571
// int __toupper(int, __locale_t);
6672
// int __tolower(int, __locale_t);
6773
// int __strcoll(const char*, const char*, __locale_t);
@@ -99,9 +105,10 @@
99105
// int __mbtowc(wchar_t*, const char*, size_t, __locale_t);
100106
// size_t __mbrlen(const char*, size_t, mbstate_t*, __locale_t);
101107
// size_t __mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*, __locale_t);
102-
// int __snprintf(char*, size_t, __locale_t, const char*, ...);
103-
// int __asprintf(char**, __locale_t, const char*, ...);
104-
// int __sscanf(const char*, __locale_t, const char*, ...);
108+
//
109+
// int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers
110+
// int __asprintf(char**, __locale_t, const char*, ...); // required by the headers
111+
// int __sscanf(const char*, __locale_t, const char*, ...); // required by the headers
105112
// }
106113

107114
#if defined(__APPLE__)
@@ -143,8 +150,19 @@ namespace __locale {
143150
//
144151
// Locale management
145152
//
153+
# define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
154+
# define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
155+
# define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
156+
# define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
157+
# define _LIBCPP_TIME_MASK LC_TIME_MASK
158+
# define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
159+
# define _LIBCPP_ALL_MASK LC_ALL_MASK
160+
# define _LIBCPP_LC_ALL LC_ALL
161+
146162
using __locale_t _LIBCPP_NODEBUG = locale_t;
147-
using __lconv_t _LIBCPP_NODEBUG = lconv;
163+
164+
# if defined(_LIBCPP_BUILDING_LIBRARY)
165+
using __lconv_t _LIBCPP_NODEBUG = lconv;
148166

149167
inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) {
150168
return newlocale(__category_mask, __name, __loc);
@@ -157,15 +175,7 @@ inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __loc
157175
inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { freelocale(__loc); }
158176

159177
inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { return __libcpp_localeconv_l(__loc); }
160-
161-
# define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK
162-
# define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK
163-
# define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK
164-
# define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK
165-
# define _LIBCPP_TIME_MASK LC_TIME_MASK
166-
# define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK
167-
# define _LIBCPP_ALL_MASK LC_ALL_MASK
168-
# define _LIBCPP_LC_ALL LC_ALL
178+
# endif // _LIBCPP_BUILDING_LIBRARY
169179

170180
//
171181
// Strtonum functions
@@ -194,10 +204,15 @@ __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
194204
//
195205
// Character manipulation functions
196206
//
207+
# if defined(_LIBCPP_BUILDING_LIBRARY)
197208
inline _LIBCPP_HIDE_FROM_ABI int __islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); }
198209
inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __ch, __locale_t __loc) { return isupper_l(__ch, __loc); }
210+
# endif
211+
199212
inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); }
200213
inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); }
214+
215+
# if defined(_LIBCPP_BUILDING_LIBRARY)
201216
inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) {
202217
return strcoll_l(__s1, __s2, __loc);
203218
}
@@ -207,7 +222,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, s
207222
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __ch, __locale_t __loc) { return toupper_l(__ch, __loc); }
208223
inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __ch, __locale_t __loc) { return tolower_l(__ch, __loc); }
209224

210-
# if _LIBCPP_HAS_WIDE_CHARACTERS
225+
# if _LIBCPP_HAS_WIDE_CHARACTERS
211226
inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __s1, const wchar_t* __s2, __locale_t __loc) {
212227
return wcscoll_l(__s1, __s2, __loc);
213228
}
@@ -229,7 +244,7 @@ inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __ch, __locale_t __loc) { ret
229244
inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __ch, __locale_t __loc) { return iswxdigit_l(__ch, __loc); }
230245
inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __ch, __locale_t __loc) { return towupper_l(__ch, __loc); }
231246
inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __ch, __locale_t __loc) { return towlower_l(__ch, __loc); }
232-
# endif
247+
# endif
233248

234249
inline _LIBCPP_HIDE_FROM_ABI size_t
235250
__strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __locale_t __loc) {
@@ -242,7 +257,7 @@ __strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __loca
242257
inline _LIBCPP_HIDE_FROM_ABI decltype(__libcpp_mb_cur_max_l(__locale_t())) __mb_len_max(__locale_t __loc) {
243258
return __libcpp_mb_cur_max_l(__loc);
244259
}
245-
# if _LIBCPP_HAS_WIDE_CHARACTERS
260+
# if _LIBCPP_HAS_WIDE_CHARACTERS
246261
inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __ch, __locale_t __loc) { return __libcpp_btowc_l(__ch, __loc); }
247262
inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __ch, __locale_t __loc) { return __libcpp_wctob_l(__ch, __loc); }
248263
inline _LIBCPP_HIDE_FROM_ABI size_t
@@ -270,7 +285,8 @@ inline _LIBCPP_HIDE_FROM_ABI size_t
270285
__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
271286
return __libcpp_mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
272287
}
273-
# endif
288+
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
289+
# endif // _LIBCPP_BUILDING_LIBRARY
274290

275291
_LIBCPP_DIAGNOSTIC_PUSH
276292
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")

libcxx/include/__locale_dir/support/bsd_like.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ namespace __locale {
4646
#define _LIBCPP_LC_ALL LC_ALL
4747

4848
using __locale_t = ::locale_t;
49-
using __lconv_t = std::lconv;
49+
#if defined(_LIBCPP_BUILDING_LIBRARY)
50+
using __lconv_t = std::lconv;
5051

5152
inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __locale, __locale_t __base) {
5253
return ::newlocale(__category_mask, __locale, __base);
@@ -59,6 +60,7 @@ inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __loc
5960
}
6061

6162
inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { return ::localeconv_l(__loc); }
63+
#endif // _LIBCPP_BUILDING_LIBRARY
6264

6365
//
6466
// Strtonum functions
@@ -87,14 +89,17 @@ __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) {
8789
//
8890
// Character manipulation functions
8991
//
92+
#if defined(_LIBCPP_BUILDING_LIBRARY)
9093
inline _LIBCPP_HIDE_FROM_ABI int __islower(int __c, __locale_t __loc) { return ::islower_l(__c, __loc); }
9194

9295
inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __c, __locale_t __loc) { return ::isupper_l(__c, __loc); }
96+
#endif
9397

9498
inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t __loc) { return ::isdigit_l(__c, __loc); }
9599

96100
inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t __loc) { return ::isxdigit_l(__c, __loc); }
97101

102+
#if defined(_LIBCPP_BUILDING_LIBRARY)
98103
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t __loc) { return ::toupper_l(__c, __loc); }
99104

100105
inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t __loc) { return ::tolower_l(__c, __loc); }
@@ -107,7 +112,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, s
107112
return ::strxfrm_l(__dest, __src, __n, __loc);
108113
}
109114

110-
#if _LIBCPP_HAS_WIDE_CHARACTERS
115+
# if _LIBCPP_HAS_WIDE_CHARACTERS
111116
inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t __loc) {
112117
return ::iswctype_l(__c, __type, __loc);
113118
}
@@ -143,7 +148,7 @@ inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t*
143148
inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) {
144149
return ::wcsxfrm_l(__dest, __src, __n, __loc);
145150
}
146-
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
151+
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
147152

148153
inline _LIBCPP_HIDE_FROM_ABI size_t
149154
__strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t __loc) {
@@ -155,14 +160,14 @@ __strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm,
155160
//
156161
inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc) { return MB_CUR_MAX_L(__loc); }
157162

158-
#if _LIBCPP_HAS_WIDE_CHARACTERS
163+
# if _LIBCPP_HAS_WIDE_CHARACTERS
159164
inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) { return ::btowc_l(__c, __loc); }
160165

161166
inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __c, __locale_t __loc) { return ::wctob_l(__c, __loc); }
162167

163168
inline _LIBCPP_HIDE_FROM_ABI size_t
164169
__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
165-
return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
170+
return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc); // wcsnrtombs is a POSIX extension
166171
}
167172

168173
inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
@@ -171,7 +176,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t
171176

172177
inline _LIBCPP_HIDE_FROM_ABI size_t
173178
__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
174-
return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
179+
return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc); // mbsnrtowcs is a POSIX extension
175180
}
176181

177182
inline _LIBCPP_HIDE_FROM_ABI size_t
@@ -191,7 +196,8 @@ inline _LIBCPP_HIDE_FROM_ABI size_t
191196
__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) {
192197
return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc);
193198
}
194-
#endif
199+
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
200+
#endif // _LIBCPP_BUILDING_LIBRARY
195201

196202
_LIBCPP_DIAGNOSTIC_PUSH
197203
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")
@@ -211,7 +217,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __
211217
template <class... _Args>
212218
_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf(
213219
char** __s, __locale_t __loc, const char* __format, _Args&&... __args) {
214-
return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...);
220+
return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); // non-standard
215221
}
216222

217223
template <class... _Args>

libcxx/include/__locale_dir/support/fuchsia.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ struct __locale_guard {
5050
#define _LIBCPP_LC_ALL LC_ALL
5151

5252
using __locale_t = locale_t;
53-
using __lconv_t = std::lconv;
53+
54+
#if defined(_LIBCPP_BUILDING_LIBRARY)
55+
using __lconv_t = std::lconv;
5456

5557
inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) {
5658
return ::newlocale(__category_mask, __name, __loc);
@@ -74,7 +76,7 @@ inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_len_max(__locale_t __loc)
7476
__locale_guard __current(__loc);
7577
return MB_CUR_MAX;
7678
}
77-
#if _LIBCPP_HAS_WIDE_CHARACTERS
79+
# if _LIBCPP_HAS_WIDE_CHARACTERS
7880
inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __ch, __locale_t __loc) {
7981
__locale_guard __current(__loc);
8082
return std::btowc(__ch);
@@ -115,7 +117,8 @@ __mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps,
115117
__locale_guard __current(__loc);
116118
return ::mbsrtowcs(__dest, __src, __len, __ps);
117119
}
118-
#endif
120+
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
121+
#endif // _LIBCPP_BUILDING_LIBRARY
119122

120123
_LIBCPP_DIAGNOSTIC_PUSH
121124
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat")

libcxx/include/__locale_dir/support/no_locale/characters.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,17 @@ namespace __locale {
2929
//
3030
// Character manipulation functions
3131
//
32+
#if defined(_LIBCPP_BUILDING_LIBRARY)
3233
inline _LIBCPP_HIDE_FROM_ABI int __islower(int __c, __locale_t) { return std::islower(__c); }
3334

3435
inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __c, __locale_t) { return std::isupper(__c); }
36+
#endif
3537

3638
inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __c, __locale_t) { return std::isdigit(__c); }
3739

3840
inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __c, __locale_t) { return std::isxdigit(__c); }
3941

42+
#if defined(_LIBCPP_BUILDING_LIBRARY)
4043
inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __c, __locale_t) { return std::toupper(__c); }
4144

4245
inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __c, __locale_t) { return std::tolower(__c); }
@@ -49,7 +52,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, s
4952
return std::strxfrm(__dest, __src, __n);
5053
}
5154

52-
#if _LIBCPP_HAS_WIDE_CHARACTERS
55+
# if _LIBCPP_HAS_WIDE_CHARACTERS
5356
inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __c, wctype_t __type, __locale_t) {
5457
return std::iswctype(__c, __type);
5558
}
@@ -85,12 +88,13 @@ inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __ws1, const wchar_t*
8588
inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t) {
8689
return std::wcsxfrm(__dest, __src, __n);
8790
}
88-
#endif // _LIBCPP_HAS_WIDE_CHARACTERS
91+
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
8992

9093
inline _LIBCPP_HIDE_FROM_ABI size_t
9194
__strftime(char* __s, size_t __max, const char* __format, const struct tm* __tm, __locale_t) {
9295
return std::strftime(__s, __max, __format, __tm);
9396
}
97+
#endif // _LIBCPP_BUILDING_LIBRARY
9498

9599
} // namespace __locale
96100
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)