Skip to content

[cherry-pick stable/20230725] [Modules] Make clang modules for the C standard library headers #7953

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions clang/lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,7 @@ bool Module::directlyUses(const Module *Requested) {
// Anyone is allowed to use our builtin stdarg.h and stddef.h and their
// accompanying modules.
if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" ||
Requested->getTopLevelModuleName() == "_Builtin_stddef" ||
(!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t"))
Requested->getTopLevelModuleName() == "_Builtin_stddef")
return true;

if (NoUndeclaredIncludes)
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Headers/__stddef_max_align_t.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---===
/*===---- __stddef_max_align_t.h - Definition of max_align_t ---------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Headers/__stddef_null.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(NULL) || !__has_feature(modules)

/* linux/stddef.h will define NULL to 0. glibc (and other) headers then define
* __need_NULL and rely on stddef.h to redefine NULL to the correct value again.
* Modules don't support redefining macros like that, but support that pattern
* in the non-modules case.
*/
#undef NULL

#ifdef __cplusplus
#if !defined(__MINGW32__) && !defined(_MSC_VER)
#define NULL __null
Expand All @@ -17,3 +25,5 @@
#else
#define NULL ((void *)0)
#endif

#endif
11 changes: 6 additions & 5 deletions clang/lib/Headers/__stddef_nullptr_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(_NULLPTR_T) || __has_feature(modules)
/* Always define nullptr_t when modules are available. */
#if !__has_feature(modules)
#ifndef _NULLPTR_T
#define _NULLPTR_T
#endif

#ifdef __cplusplus
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
namespace std {
typedef decltype(nullptr) nullptr_t;
}
using ::std::nullptr_t;
#endif
#else
/* FIXME: This is using the placeholder dates Clang produces for these macros
in C2x mode; switch to the correct values once they've been published. */
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
typedef typeof(nullptr) nullptr_t;
#endif

#endif
3 changes: 1 addition & 2 deletions clang/lib/Headers/__stddef_offsetof.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(offsetof) || __has_feature(modules)
/* Always define offsetof when modules are available. */
#ifndef offsetof
#define offsetof(t, d) __builtin_offsetof(t, d)
#endif
7 changes: 3 additions & 4 deletions clang/lib/Headers/__stddef_ptrdiff_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(_PTRDIFF_T) || __has_feature(modules)
/* Always define ptrdiff_t when modules are available. */
#if !__has_feature(modules)
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
#endif

typedef __PTRDIFF_TYPE__ ptrdiff_t;

#endif
7 changes: 3 additions & 4 deletions clang/lib/Headers/__stddef_rsize_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(_RSIZE_T) || __has_feature(modules)
/* Always define rsize_t when modules are available. */
#if !__has_feature(modules)
#ifndef _RSIZE_T
#define _RSIZE_T
#endif

typedef __SIZE_TYPE__ rsize_t;

#endif
7 changes: 3 additions & 4 deletions clang/lib/Headers/__stddef_size_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(_SIZE_T) || __has_feature(modules)
/* Always define size_t when modules are available. */
#if !__has_feature(modules)
#ifndef _SIZE_T
#define _SIZE_T
#endif

typedef __SIZE_TYPE__ size_t;

#endif
3 changes: 1 addition & 2 deletions clang/lib/Headers/__stddef_unreachable.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(unreachable) || __has_feature(modules)
/* Always define unreachable when modules are available. */
#ifndef unreachable
#define unreachable() __builtin_unreachable()
#endif
12 changes: 7 additions & 5 deletions clang/lib/Headers/__stddef_wchar_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
*/

#if !defined(__cplusplus) || (defined(_MSC_VER) && !_NATIVE_WCHAR_T_DEFINED)
/* Always define wchar_t when modules are available. */
#if !defined(_WCHAR_T) || __has_feature(modules)
#if !__has_feature(modules)

#ifndef _WCHAR_T
#define _WCHAR_T
#if defined(_MSC_EXTENSIONS)

#ifdef _MSC_EXTENSIONS
#define _WCHAR_T_DEFINED
#endif
#endif

typedef __WCHAR_TYPE__ wchar_t;

#endif

#endif
7 changes: 3 additions & 4 deletions clang/lib/Headers/__stddef_wint_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
*===-----------------------------------------------------------------------===
*/

/* Always define wint_t when modules are available. */
#if !defined(_WINT_T) || __has_feature(modules)
#if !__has_feature(modules)
#ifndef _WINT_T
#define _WINT_T
#endif

typedef __WINT_TYPE__ wint_t;

#endif
159 changes: 157 additions & 2 deletions clang/lib/Headers/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,164 @@ module _Builtin_intrinsics [system] [extern_c] {
}
}

module _Builtin_stddef_max_align_t [system] [extern_c] {
header "__stddef_max_align_t.h"
// Start -fbuiltin-headers-in-system-modules affected modules

// The following modules all ignore their top level headers
// when -fbuiltin-headers-in-system-modules is passed, and
// most of those headers join system modules when present.

// e.g. if -fbuiltin-headers-in-system-modules is passed, then
// float.h will not be in the _Builtin_float module (that module
// will be empty). If there is a system module that declares
// `header "float.h"`, then the builtin float.h will join
// that module. The system float.h (if present) will be treated
// as a textual header in the sytem module.
module _Builtin_float [system] {
header "float.h"
export *
}

module _Builtin_inttypes [system] {
header "inttypes.h"
export *
}

module _Builtin_iso646 [system] {
header "iso646.h"
export *
}

module _Builtin_limits [system] {
header "limits.h"
export *
}

module _Builtin_stdalign [system] {
header "stdalign.h"
export *
}

// When -fbuiltin-headers-in-system-modules is passed, only
// the top level headers are removed, the implementation headers
// will always be in their submodules. That means when stdarg.h
// is included, it will still import this module and make the
// appropriate submodules visible.
module _Builtin_stdarg [system] {
textual header "stdarg.h"

explicit module __gnuc_va_list {
header "__stdarg___gnuc_va_list.h"
export *
}

explicit module __va_copy {
header "__stdarg___va_copy.h"
export *
}

explicit module va_arg {
header "__stdarg_va_arg.h"
export *
}

explicit module va_copy {
header "__stdarg_va_copy.h"
export *
}

explicit module va_list {
header "__stdarg_va_list.h"
export *
}
}

module _Builtin_stdatomic [system] {
header "stdatomic.h"
export *
}

module _Builtin_stdbool [system] {
header "stdbool.h"
export *
}

module _Builtin_stddef [system] {
textual header "stddef.h"

explicit module max_align_t {
header "__stddef_max_align_t.h"
export *
}

explicit module null {
header "__stddef_null.h"
export *
}

explicit module nullptr_t {
header "__stddef_nullptr_t.h"
export *
}

explicit module offsetof {
header "__stddef_offsetof.h"
export *
}

explicit module ptrdiff_t {
header "__stddef_ptrdiff_t.h"
export *
}

explicit module rsize_t {
header "__stddef_rsize_t.h"
export *
}

explicit module size_t {
header "__stddef_size_t.h"
export *
}

explicit module unreachable {
header "__stddef_unreachable.h"
export *
}

explicit module wchar_t {
header "__stddef_wchar_t.h"
export *
}
}

/* wint_t is provided by <wchar.h> and not <stddef.h>. It's here
* for compatibility, but must be explicitly requested. Therefore
* __stddef_wint_t.h is not part of _Builtin_stddef. */
module _Builtin_stddef_wint_t [system] {
header "__stddef_wint_t.h"
export *
}

module _Builtin_stdint [system] {
header "stdint.h"
export *
}

module _Builtin_stdnoreturn [system] {
header "stdnoreturn.h"
export *
}

module _Builtin_tgmath [system] {
header "tgmath.h"
export *
}

module _Builtin_unwind [system] {
header "unwind.h"
export *
}
// End -fbuiltin-headers-in-system-modules affected modules

module opencl_c {
requires opencl
Expand Down
28 changes: 25 additions & 3 deletions clang/lib/Headers/stdarg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,31 @@
*===-----------------------------------------------------------------------===
*/

#if !defined(__STDARG_H) || defined(__need___va_list) || \
defined(__need_va_list) || defined(__need_va_arg) || \
defined(__need___va_copy) || defined(__need_va_copy)
/*
* This header is designed to be included multiple times. If any of the __need_
* macros are defined, then only that subset of interfaces are provided. This
* can be useful for POSIX headers that need to not expose all of stdarg.h, but
* need to use some of its interfaces. Otherwise this header provides all of
* the expected interfaces.
*
* When clang modules are enabled, this header is a textual header. It ignores
* its header guard so that multiple submodules can export its interfaces.
* Take module SM with submodules A and B, whose headers both include stdarg.h
* When SM.A builds, __STDARG_H will be defined. When SM.B builds, the
* definition from SM.A will leak when building without local submodule
* visibility. stdarg.h wouldn't include any of its implementation headers, and
* SM.B wouldn't import any of the stdarg modules, and SM.B's `export *`
* wouldn't export any stdarg interfaces as expected. However, since stdarg.h
* ignores its header guard when building with modules, it all works as
* expected.
*
* When clang modules are not enabled, the header guards can function in the
* normal simple fashion.
*/
#if !defined(__STDARG_H) || __has_feature(modules) || \
defined(__need___va_list) || defined(__need_va_list) || \
defined(__need_va_arg) || defined(__need___va_copy) || \
defined(__need_va_copy)

#if !defined(__need___va_list) && !defined(__need_va_list) && \
!defined(__need_va_arg) && !defined(__need___va_copy) && \
Expand Down
Loading