Skip to content

Commit fb4d85b

Browse files
committed
[libc++] Reduce the dependency of the locale base API on the base system from the headers
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 #117630
1 parent 6f5e5b6 commit fb4d85b

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

libcxx/include/__locale_dir/locale_base_api.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@
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: I think __uselocale() is not necessary if we refactor a bit.
2730
// TODO: __localeconv shouldn't take a reference, but the Windows implementation doesn't allow copying __locale_t
31+
// TODO: Eliminate the need for any of these functions from the headers.
2832
//
2933
// Locale management
3034
// -----------------
3135
// namespace __locale {
32-
// using __locale_t = implementation-defined;
36+
// using __locale_t = implementation-defined; // required by the headers
3337
// __locale_t __uselocale(__locale_t);
3438
// __locale_t __newlocale(int, const char*, __locale_t);
3539
// void __freelocale(__locale_t);
@@ -51,8 +55,8 @@
5155
// namespace __locale {
5256
// int __islower(int, __locale_t);
5357
// int __isupper(int, __locale_t);
54-
// int __isdigit(int, __locale_t);
55-
// int __isxdigit(int, __locale_t);
58+
// int __isdigit(int, __locale_t); // required by the headers
59+
// int __isxdigit(int, __locale_t); // required by the headers
5660
// int __toupper(int, __locale_t);
5761
// int __tolower(int, __locale_t);
5862
// int __strcoll(const char*, const char*, __locale_t);
@@ -89,9 +93,10 @@
8993
// int __mbtowc(wchar_t*, const char*, size_t, __locale_t);
9094
// size_t __mbrlen(const char*, size_t, mbstate_t*, __locale_t);
9195
// size_t __mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*, __locale_t);
92-
// int __snprintf(char*, size_t, __locale_t, const char*, ...);
93-
// int __asprintf(char**, __locale_t, const char*, ...);
94-
// int __sscanf(const char*, __locale_t, const char*, ...);
96+
//
97+
// int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers
98+
// int __asprintf(char**, __locale_t, const char*, ...); // required by the headers
99+
// int __sscanf(const char*, __locale_t, const char*, ...); // required by the headers
95100
// }
96101

97102
#if defined(__APPLE__)

libcxx/include/__locale_dir/support/bsd_like.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,23 @@ inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) { return
144144

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

147+
#ifdef _LIBCPP_BUILDING_LIBRARY
147148
inline _LIBCPP_HIDE_FROM_ABI size_t
148149
__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
149150
return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
150151
}
152+
#endif
151153

152154
inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
153155
return ::wcrtomb_l(__s, __wc, __ps, __loc);
154156
}
155157

158+
#ifdef _LIBCPP_BUILDING_LIBRARY
156159
inline _LIBCPP_HIDE_FROM_ABI size_t
157160
__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
158161
return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
159162
}
163+
#endif
160164

161165
inline _LIBCPP_HIDE_FROM_ABI size_t
162166
__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# ===----------------------------------------------------------------------===##
2+
#
3+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# ===----------------------------------------------------------------------===##
8+
9+
# Make sure that libc++ headers work when defining _XOPEN_SOURCE=500.
10+
# We may not want to guarantee this forever, but since this works today and
11+
# it's something that users rely on, it makes sense to put a test on it.
12+
#
13+
# https://github.com/llvm/llvm-project/issues/117630
14+
15+
# RUN: %{python} %s %{libcxx-dir}/utils
16+
17+
import sys
18+
19+
sys.path.append(sys.argv[1])
20+
from libcxx.header_information import (
21+
lit_header_restrictions,
22+
lit_header_undeprecations,
23+
public_headers,
24+
)
25+
26+
for header in public_headers:
27+
for version in (500, 600, 700):
28+
# TODO: <fstream> currently uses ::fseeko unguarded, which fails with _XOPEN_SOURCE=500.
29+
if header == 'fstream' and version == 500:
30+
continue
31+
32+
print(f"""\
33+
//--- {header}.xopen_source_{version}.compile.pass.cpp
34+
{lit_header_restrictions.get(header, '')}
35+
{lit_header_undeprecations.get(header, '')}
36+
37+
// ADDITIONAL_COMPILE_FLAGS: -D_XOPEN_SOURCE={version}
38+
39+
#include <{header}>
40+
"""
41+
)

0 commit comments

Comments
 (0)