Skip to content

Commit a486593

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 f308af7 commit a486593

File tree

3 files changed

+57
-6
lines changed

3 files changed

+57
-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,12 +23,16 @@
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);
@@ -60,8 +64,8 @@
6064
// namespace __locale {
6165
// int __islower(int, __locale_t);
6266
// int __isupper(int, __locale_t);
63-
// int __isdigit(int, __locale_t);
64-
// int __isxdigit(int, __locale_t);
67+
// int __isdigit(int, __locale_t); // required by the headers
68+
// int __isxdigit(int, __locale_t); // required by the headers
6569
// int __toupper(int, __locale_t);
6670
// int __tolower(int, __locale_t);
6771
// int __strcoll(const char*, const char*, __locale_t);
@@ -99,9 +103,10 @@
99103
// int __mbtowc(wchar_t*, const char*, size_t, __locale_t);
100104
// size_t __mbrlen(const char*, size_t, mbstate_t*, __locale_t);
101105
// 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*, ...);
106+
//
107+
// int __snprintf(char*, size_t, __locale_t, const char*, ...); // required by the headers
108+
// int __asprintf(char**, __locale_t, const char*, ...); // required by the headers
109+
// int __sscanf(const char*, __locale_t, const char*, ...); // required by the headers
105110
// }
106111

107112
#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
@@ -160,19 +160,23 @@ inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __c, __locale_t __loc) { return
160160

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

163+
# ifdef _LIBCPP_BUILDING_LIBRARY
163164
inline _LIBCPP_HIDE_FROM_ABI size_t
164165
__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) {
165166
return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc);
166167
}
168+
# endif
167169

168170
inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __wc, mbstate_t* __ps, __locale_t __loc) {
169171
return ::wcrtomb_l(__s, __wc, __ps, __loc);
170172
}
171173

174+
# ifdef _LIBCPP_BUILDING_LIBRARY
172175
inline _LIBCPP_HIDE_FROM_ABI size_t
173176
__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) {
174177
return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc);
175178
}
179+
# endif
176180

177181
inline _LIBCPP_HIDE_FROM_ABI size_t
178182
__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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(
33+
f"""\
34+
//--- {header}.xopen_source_{version}.compile.pass.cpp
35+
{lit_header_restrictions.get(header, '')}
36+
{lit_header_undeprecations.get(header, '')}
37+
38+
// ADDITIONAL_COMPILE_FLAGS: -D_XOPEN_SOURCE={version}
39+
40+
#include <{header}>
41+
"""
42+
)

0 commit comments

Comments
 (0)