Skip to content

Commit 54cbee1

Browse files
Merge pull request #7953 from ian-twilightcoder/cstdlib-modules
[cherry-pick stable/20230725] [Modules] Make clang modules for the C standard library headers
2 parents 6e97019 + 33825da commit 54cbee1

35 files changed

+752
-162
lines changed

clang/lib/Basic/Module.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,7 @@ bool Module::directlyUses(const Module *Requested) {
308308
// Anyone is allowed to use our builtin stdarg.h and stddef.h and their
309309
// accompanying modules.
310310
if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" ||
311-
Requested->getTopLevelModuleName() == "_Builtin_stddef" ||
312-
(!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t"))
311+
Requested->getTopLevelModuleName() == "_Builtin_stddef")
313312
return true;
314313

315314
if (NoUndeclaredIncludes)

clang/lib/Headers/__stddef_max_align_t.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---===
1+
/*===---- __stddef_max_align_t.h - Definition of max_align_t ---------------===
22
*
33
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
* See https://llvm.org/LICENSE.txt for license information.

clang/lib/Headers/__stddef_null.h

+10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10+
#if !defined(NULL) || !__has_feature(modules)
11+
12+
/* linux/stddef.h will define NULL to 0. glibc (and other) headers then define
13+
* __need_NULL and rely on stddef.h to redefine NULL to the correct value again.
14+
* Modules don't support redefining macros like that, but support that pattern
15+
* in the non-modules case.
16+
*/
1017
#undef NULL
18+
1119
#ifdef __cplusplus
1220
#if !defined(__MINGW32__) && !defined(_MSC_VER)
1321
#define NULL __null
@@ -17,3 +25,5 @@
1725
#else
1826
#define NULL ((void *)0)
1927
#endif
28+
29+
#endif

clang/lib/Headers/__stddef_nullptr_t.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(_NULLPTR_T) || __has_feature(modules)
11-
/* Always define nullptr_t when modules are available. */
12-
#if !__has_feature(modules)
10+
#ifndef _NULLPTR_T
1311
#define _NULLPTR_T
14-
#endif
12+
1513
#ifdef __cplusplus
1614
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
1715
namespace std {
1816
typedef decltype(nullptr) nullptr_t;
1917
}
2018
using ::std::nullptr_t;
2119
#endif
22-
#else
20+
/* FIXME: This is using the placeholder dates Clang produces for these macros
21+
in C2x mode; switch to the correct values once they've been published. */
22+
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
2323
typedef typeof(nullptr) nullptr_t;
2424
#endif
25+
2526
#endif

clang/lib/Headers/__stddef_offsetof.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(offsetof) || __has_feature(modules)
11-
/* Always define offsetof when modules are available. */
10+
#ifndef offsetof
1211
#define offsetof(t, d) __builtin_offsetof(t, d)
1312
#endif

clang/lib/Headers/__stddef_ptrdiff_t.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(_PTRDIFF_T) || __has_feature(modules)
11-
/* Always define ptrdiff_t when modules are available. */
12-
#if !__has_feature(modules)
10+
#ifndef _PTRDIFF_T
1311
#define _PTRDIFF_T
14-
#endif
12+
1513
typedef __PTRDIFF_TYPE__ ptrdiff_t;
14+
1615
#endif

clang/lib/Headers/__stddef_rsize_t.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(_RSIZE_T) || __has_feature(modules)
11-
/* Always define rsize_t when modules are available. */
12-
#if !__has_feature(modules)
10+
#ifndef _RSIZE_T
1311
#define _RSIZE_T
14-
#endif
12+
1513
typedef __SIZE_TYPE__ rsize_t;
14+
1615
#endif

clang/lib/Headers/__stddef_size_t.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(_SIZE_T) || __has_feature(modules)
11-
/* Always define size_t when modules are available. */
12-
#if !__has_feature(modules)
10+
#ifndef _SIZE_T
1311
#define _SIZE_T
14-
#endif
12+
1513
typedef __SIZE_TYPE__ size_t;
14+
1615
#endif

clang/lib/Headers/__stddef_unreachable.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(unreachable) || __has_feature(modules)
11-
/* Always define unreachable when modules are available. */
10+
#ifndef unreachable
1211
#define unreachable() __builtin_unreachable()
1312
#endif

clang/lib/Headers/__stddef_wchar_t.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
*/
99

1010
#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
11-
/* Always define wchar_t when modules are available. */
12-
#if !defined(_WCHAR_T) || __has_feature(modules)
13-
#if !__has_feature(modules)
11+
12+
#ifndef _WCHAR_T
1413
#define _WCHAR_T
15-
#if defined(_MSC_EXTENSIONS)
14+
15+
#ifdef _MSC_EXTENSIONS
1616
#define _WCHAR_T_DEFINED
1717
#endif
18-
#endif
18+
1919
typedef __WCHAR_TYPE__ wchar_t;
20+
2021
#endif
22+
2123
#endif

clang/lib/Headers/__stddef_wint_t.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
/* Always define wint_t when modules are available. */
11-
#if !defined(_WINT_T) || __has_feature(modules)
12-
#if !__has_feature(modules)
10+
#ifndef _WINT_T
1311
#define _WINT_T
14-
#endif
12+
1513
typedef __WINT_TYPE__ wint_t;
14+
1615
#endif

clang/lib/Headers/module.modulemap

+157-2
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,164 @@ module _Builtin_intrinsics [system] [extern_c] {
153153
}
154154
}
155155

156-
module _Builtin_stddef_max_align_t [system] [extern_c] {
157-
header "__stddef_max_align_t.h"
156+
// Start -fbuiltin-headers-in-system-modules affected modules
157+
158+
// The following modules all ignore their top level headers
159+
// when -fbuiltin-headers-in-system-modules is passed, and
160+
// most of those headers join system modules when present.
161+
162+
// e.g. if -fbuiltin-headers-in-system-modules is passed, then
163+
// float.h will not be in the _Builtin_float module (that module
164+
// will be empty). If there is a system module that declares
165+
// `header "float.h"`, then the builtin float.h will join
166+
// that module. The system float.h (if present) will be treated
167+
// as a textual header in the sytem module.
168+
module _Builtin_float [system] {
169+
header "float.h"
170+
export *
171+
}
172+
173+
module _Builtin_inttypes [system] {
174+
header "inttypes.h"
175+
export *
176+
}
177+
178+
module _Builtin_iso646 [system] {
179+
header "iso646.h"
180+
export *
181+
}
182+
183+
module _Builtin_limits [system] {
184+
header "limits.h"
185+
export *
186+
}
187+
188+
module _Builtin_stdalign [system] {
189+
header "stdalign.h"
190+
export *
191+
}
192+
193+
// When -fbuiltin-headers-in-system-modules is passed, only
194+
// the top level headers are removed, the implementation headers
195+
// will always be in their submodules. That means when stdarg.h
196+
// is included, it will still import this module and make the
197+
// appropriate submodules visible.
198+
module _Builtin_stdarg [system] {
199+
textual header "stdarg.h"
200+
201+
explicit module __gnuc_va_list {
202+
header "__stdarg___gnuc_va_list.h"
203+
export *
204+
}
205+
206+
explicit module __va_copy {
207+
header "__stdarg___va_copy.h"
208+
export *
209+
}
210+
211+
explicit module va_arg {
212+
header "__stdarg_va_arg.h"
213+
export *
214+
}
215+
216+
explicit module va_copy {
217+
header "__stdarg_va_copy.h"
218+
export *
219+
}
220+
221+
explicit module va_list {
222+
header "__stdarg_va_list.h"
223+
export *
224+
}
225+
}
226+
227+
module _Builtin_stdatomic [system] {
228+
header "stdatomic.h"
229+
export *
230+
}
231+
232+
module _Builtin_stdbool [system] {
233+
header "stdbool.h"
234+
export *
235+
}
236+
237+
module _Builtin_stddef [system] {
238+
textual header "stddef.h"
239+
240+
explicit module max_align_t {
241+
header "__stddef_max_align_t.h"
242+
export *
243+
}
244+
245+
explicit module null {
246+
header "__stddef_null.h"
247+
export *
248+
}
249+
250+
explicit module nullptr_t {
251+
header "__stddef_nullptr_t.h"
252+
export *
253+
}
254+
255+
explicit module offsetof {
256+
header "__stddef_offsetof.h"
257+
export *
258+
}
259+
260+
explicit module ptrdiff_t {
261+
header "__stddef_ptrdiff_t.h"
262+
export *
263+
}
264+
265+
explicit module rsize_t {
266+
header "__stddef_rsize_t.h"
267+
export *
268+
}
269+
270+
explicit module size_t {
271+
header "__stddef_size_t.h"
272+
export *
273+
}
274+
275+
explicit module unreachable {
276+
header "__stddef_unreachable.h"
277+
export *
278+
}
279+
280+
explicit module wchar_t {
281+
header "__stddef_wchar_t.h"
282+
export *
283+
}
284+
}
285+
286+
/* wint_t is provided by <wchar.h> and not <stddef.h>. It's here
287+
* for compatibility, but must be explicitly requested. Therefore
288+
* __stddef_wint_t.h is not part of _Builtin_stddef. */
289+
module _Builtin_stddef_wint_t [system] {
290+
header "__stddef_wint_t.h"
291+
export *
292+
}
293+
294+
module _Builtin_stdint [system] {
295+
header "stdint.h"
296+
export *
297+
}
298+
299+
module _Builtin_stdnoreturn [system] {
300+
header "stdnoreturn.h"
301+
export *
302+
}
303+
304+
module _Builtin_tgmath [system] {
305+
header "tgmath.h"
306+
export *
307+
}
308+
309+
module _Builtin_unwind [system] {
310+
header "unwind.h"
311+
export *
158312
}
313+
// End -fbuiltin-headers-in-system-modules affected modules
159314

160315
module opencl_c {
161316
requires opencl

clang/lib/Headers/stdarg.h

+25-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,31 @@
77
*===-----------------------------------------------------------------------===
88
*/
99

10-
#if !defined(__STDARG_H) || defined(__need___va_list) || \
11-
defined(__need_va_list) || defined(__need_va_arg) || \
12-
defined(__need___va_copy) || defined(__need_va_copy)
10+
/*
11+
* This header is designed to be included multiple times. If any of the __need_
12+
* macros are defined, then only that subset of interfaces are provided. This
13+
* can be useful for POSIX headers that need to not expose all of stdarg.h, but
14+
* need to use some of its interfaces. Otherwise this header provides all of
15+
* the expected interfaces.
16+
*
17+
* When clang modules are enabled, this header is a textual header. It ignores
18+
* its header guard so that multiple submodules can export its interfaces.
19+
* Take module SM with submodules A and B, whose headers both include stdarg.h
20+
* When SM.A builds, __STDARG_H will be defined. When SM.B builds, the
21+
* definition from SM.A will leak when building without local submodule
22+
* visibility. stdarg.h wouldn't include any of its implementation headers, and
23+
* SM.B wouldn't import any of the stdarg modules, and SM.B's `export *`
24+
* wouldn't export any stdarg interfaces as expected. However, since stdarg.h
25+
* ignores its header guard when building with modules, it all works as
26+
* expected.
27+
*
28+
* When clang modules are not enabled, the header guards can function in the
29+
* normal simple fashion.
30+
*/
31+
#if !defined(__STDARG_H) || __has_feature(modules) || \
32+
defined(__need___va_list) || defined(__need_va_list) || \
33+
defined(__need_va_arg) || defined(__need___va_copy) || \
34+
defined(__need_va_copy)
1335

1436
#if !defined(__need___va_list) && !defined(__need_va_list) && \
1537
!defined(__need_va_arg) && !defined(__need___va_copy) && \

0 commit comments

Comments
 (0)