diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 0fd9c1dca3998..7879a11179b6d 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -301,7 +301,8 @@ bool Module::directlyUses(const Module *Requested) { // Anyone is allowed to use our builtin stdarg.h and stddef.h and their // accompanying modules. - if (!Requested->Parent && (Requested->Name == "_Builtin_stdarg" || Requested->Name == "_Builtin_stddef")) + if (Requested->getTopLevelModuleName() == "_Builtin_stdarg" || + Requested->getTopLevelModuleName() == "_Builtin_stddef") return true; if (NoUndeclaredIncludes) diff --git a/clang/test/Modules/Inputs/System/usr/include/inttypes.h b/clang/test/Modules/Inputs/System/usr/include/inttypes.h deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/clang/test/Modules/Inputs/System/usr/include/math.h b/clang/test/Modules/Inputs/System/usr/include/math.h deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/clang/test/Modules/Inputs/System/usr/include/module.map b/clang/test/Modules/Inputs/System/usr/include/module.map index 5a15c70a394d2..1d88ca380f49a 100644 --- a/clang/test/Modules/Inputs/System/usr/include/module.map +++ b/clang/test/Modules/Inputs/System/usr/include/module.map @@ -1,24 +1,9 @@ module cstd [system] { - // Only in system headers directory - module complex { - header "complex.h" - } - // Only in compiler support directory module float_constants { header "float.h" } - // In both directories (compiler support version wins, forwards) - module inttypes { - header "inttypes.h" - } - - // Only in system headers directory - module math { - header "math.h" - } - // Only in system headers directory module stdio { header "stdio.h" diff --git a/clang/test/Modules/Inputs/System/usr/include/stdint.h b/clang/test/Modules/Inputs/System/usr/include/stdint.h index 209d54cd411ad..e8e50f90290ce 100644 --- a/clang/test/Modules/Inputs/System/usr/include/stdint.h +++ b/clang/test/Modules/Inputs/System/usr/include/stdint.h @@ -1,36 +1 @@ -#ifndef STDINT_H -#define STDINT_H - typedef int my_awesome_nonstandard_integer_type; - -// types needed by stdatomic.h - -typedef char int_least8_t; -typedef short int_least16_t; -typedef int int_least32_t; -typedef long long int int_least64_t; -typedef unsigned char uint_least8_t; -typedef unsigned short uint_least16_t; -typedef unsigned int uint_least32_t; -typedef unsigned long long uint_least64_t; - -typedef char int_fast8_t; -typedef short int_fast16_t; -typedef int int_fast32_t; -typedef long long int int_fast64_t; -typedef unsigned char uint_fast8_t; -typedef unsigned short uint_fast16_t; -typedef unsigned int uint_fast32_t; -typedef unsigned long long uint_fast64_t; - -typedef int intptr_t; -typedef unsigned int uintptr_t; -typedef int intmax_t; -typedef unsigned int uintmax_t; - -// additional types for unwind.h - -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - -#endif /* STDINT_H */ diff --git a/clang/test/Modules/Inputs/builtin-headers/builtin-modules.modulemap b/clang/test/Modules/Inputs/builtin-headers/builtin-modules.modulemap new file mode 100644 index 0000000000000..0fbb454dbb022 --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/builtin-modules.modulemap @@ -0,0 +1,29 @@ +module c_complex [system] { + header "complex.h" + export * +} + +module c_float [system] { + header "float.h" + export * +} + +module c_inttypes [system] { + header "inttypes.h" + export * +} + +module c_limits [system] { + header "limits.h" + export * +} + +module c_math [system] { + header "math.h" + export * +} + +module c_stdint [system] { + header "stdint.h" + export * +} diff --git a/clang/test/Modules/Inputs/builtin-headers/c++/module.modulemap b/clang/test/Modules/Inputs/builtin-headers/c++/module.modulemap new file mode 100644 index 0000000000000..c969f067a234f --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/c++/module.modulemap @@ -0,0 +1,4 @@ +module cpp_stdint [system] { + header "stdint.h" + export * +} diff --git a/clang/test/Modules/Inputs/builtin-headers/c++/stdint.h b/clang/test/Modules/Inputs/builtin-headers/c++/stdint.h new file mode 100644 index 0000000000000..22cebacfdb64e --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/c++/stdint.h @@ -0,0 +1,6 @@ +#ifndef CPP_STDINT_H +#define CPP_STDINT_H + +#include_next + +#endif diff --git a/clang/test/Modules/Inputs/builtin-headers/complex.h b/clang/test/Modules/Inputs/builtin-headers/complex.h new file mode 100644 index 0000000000000..b6ef3c5a35b45 --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/complex.h @@ -0,0 +1 @@ +// Required by tgmath.h diff --git a/clang/test/Modules/Inputs/System/usr/include/complex.h b/clang/test/Modules/Inputs/builtin-headers/float.h similarity index 100% rename from clang/test/Modules/Inputs/System/usr/include/complex.h rename to clang/test/Modules/Inputs/builtin-headers/float.h diff --git a/clang/test/Modules/Inputs/builtin-headers/inttypes.h b/clang/test/Modules/Inputs/builtin-headers/inttypes.h new file mode 100644 index 0000000000000..ddb6bb83b5723 --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/inttypes.h @@ -0,0 +1,12 @@ +#ifndef INTTYPES_H +#define INTTYPES_H + +// This creates an include cycle when inttypes.h and stdint.h +// are both part of the cstd module. This include will resolve +// to the C++ stdint.h, which will #include_next eventually to +// the stdint.h in this directory, and thus create the cycle +// cstd (inttypes.h) -> cpp_stdint (stdint.h) -> cstd (stdint.h). +// This cycle is worked around by cstd using [no_undeclared_includes]. +#include + +#endif diff --git a/clang/test/Modules/Inputs/builtin-headers/limits.h b/clang/test/Modules/Inputs/builtin-headers/limits.h new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/limits.h @@ -0,0 +1 @@ + diff --git a/clang/test/Modules/Inputs/builtin-headers/math.h b/clang/test/Modules/Inputs/builtin-headers/math.h new file mode 100644 index 0000000000000..b6ef3c5a35b45 --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/math.h @@ -0,0 +1 @@ +// Required by tgmath.h diff --git a/clang/test/Modules/Inputs/builtin-headers/stdint.h b/clang/test/Modules/Inputs/builtin-headers/stdint.h new file mode 100644 index 0000000000000..8f233fd7f45d6 --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/stdint.h @@ -0,0 +1,34 @@ +#ifndef STDINT_H +#define STDINT_H + +// types needed by stdatomic.h + +typedef char int_least8_t; +typedef short int_least16_t; +typedef int int_least32_t; +typedef long long int int_least64_t; +typedef unsigned char uint_least8_t; +typedef unsigned short uint_least16_t; +typedef unsigned int uint_least32_t; +typedef unsigned long long uint_least64_t; + +typedef char int_fast8_t; +typedef short int_fast16_t; +typedef int int_fast32_t; +typedef long long int int_fast64_t; +typedef unsigned char uint_fast8_t; +typedef unsigned short uint_fast16_t; +typedef unsigned int uint_fast32_t; +typedef unsigned long long uint_fast64_t; + +typedef int intptr_t; +typedef unsigned int uintptr_t; +typedef int intmax_t; +typedef unsigned int uintmax_t; + +// additional types for unwind.h + +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +#endif diff --git a/clang/test/Modules/Inputs/builtin-headers/system-modules.modulemap b/clang/test/Modules/Inputs/builtin-headers/system-modules.modulemap new file mode 100644 index 0000000000000..0161ff80fe618 --- /dev/null +++ b/clang/test/Modules/Inputs/builtin-headers/system-modules.modulemap @@ -0,0 +1,71 @@ +module cstd [system] [no_undeclared_includes] { + module complex { + header "complex.h" + export * + } + + module float { + header "float.h" + export * + } + + module inttypes { + header "inttypes.h" + export * + } + + module iso646 { + header "iso646.h" + export * + } + + module limits { + header "limits.h" + export * + } + + module math { + header "math.h" + export * + } + + module stdalign { + header "stdalign.h" + export * + } + + module stdarg { + header "stdarg.h" + export * + } + + module stdatomic { + header "stdatomic.h" + export * + } + + module stdbool { + header "stdbool.h" + export * + } + + module stddef { + header "stddef.h" + export * + } + + module stdint { + header "stdint.h" + export * + } + + module tgmath { + header "tgmath.h" + export * + } + + module unwind { + header "unwind.h" + export * + } +} diff --git a/clang/test/Modules/builtin-headers.mm b/clang/test/Modules/builtin-headers.mm new file mode 100644 index 0000000000000..4c9ddec4e99c2 --- /dev/null +++ b/clang/test/Modules/builtin-headers.mm @@ -0,0 +1,41 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -cxx-isystem %S/Inputs/builtin-headers/c++ -internal-isystem %S/Inputs/builtin-headers -fsyntax-only -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/builtin-headers/c++/module.modulemap -fmodule-map-file=%resource_dir/module.modulemap -fmodule-map-file=%S/Inputs/builtin-headers/system-modules.modulemap -fbuiltin-headers-in-system-modules -DSYSTEM_MODULES %s -verify +// RUN: rm -rf %t +// RUN: %clang_cc1 -cxx-isystem %S/Inputs/builtin-headers/c++ -internal-isystem %S/Inputs/builtin-headers -fsyntax-only -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/builtin-headers/c++/module.modulemap -fmodule-map-file=%resource_dir/module.modulemap -fmodule-map-file=%S/Inputs/builtin-headers/builtin-modules.modulemap %s -verify + +// expected-no-diagnostics + +@import cpp_stdint; + +// The builtin modules are always available, though they're mostly +// empty if -fbuiltin-headers-in-system-modules is used. +@import _Builtin_float; +@import _Builtin_inttypes; +@import _Builtin_iso646; +@import _Builtin_limits; +@import _Builtin_stdalign; +@import _Builtin_stdarg; +@import _Builtin_stdatomic; +@import _Builtin_stdbool; +@import _Builtin_stddef; +@import _Builtin_stdint; +@import _Builtin_stdnoreturn; +@import _Builtin_tgmath; +@import _Builtin_unwind; + +#ifdef SYSTEM_MODULES +// system-modules.modulemap uses the "mega module" style with +// -fbuiltin-headers-in-system-modules, and its modules cover +// the clang builtin headers. +@import cstd; +#else +// builtin-modules.modulemap uses top level modules for each +// of its headers, which allows interleaving with the builtin +// modules and libc++ modules. +@import c_complex; +@import c_float; +@import c_inttypes; +@import c_limits; +@import c_math; +@import c_stdint; +#endif diff --git a/clang/test/Modules/compiler_builtins.m b/clang/test/Modules/compiler_builtins.m index 8eeb65daa9e88..a5e6315cedc8e 100644 --- a/clang/test/Modules/compiler_builtins.m +++ b/clang/test/Modules/compiler_builtins.m @@ -1,7 +1,7 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -internal-isystem %S/Inputs/System/usr/include -verify -// RUN: %clang_cc1 -fsyntax-only -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -internal-isystem %S/Inputs/System/usr/include -verify -// RUN: %clang_cc1 -fsyntax-only -fmodules -fmodule-map-file=%resource_dir/module.modulemap -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -DNO_SYSTEM_MODULES -verify +// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -verify +// RUN: %clang_cc1 -fsyntax-only -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -verify +// RUN: %clang_cc1 -fsyntax-only -fmodules -fmodule-map-file=%resource_dir/module.modulemap -fmodules-cache-path=%t %s -I%S/Inputs/System/usr/include -verify // expected-no-diagnostics #ifdef __SSE__ @@ -11,19 +11,3 @@ #ifdef __AVX2__ @import _Builtin_intrinsics.intel.avx2; #endif - -#ifndef NO_SYSTEM_MODULES -@import _Builtin_float; -@import _Builtin_inttypes; -@import _Builtin_iso646; -@import _Builtin_limits; -@import _Builtin_stdalign; -@import _Builtin_stdarg; -@import _Builtin_stdatomic; -@import _Builtin_stdbool; -@import _Builtin_stddef; -@import _Builtin_stdint; -@import _Builtin_stdnoreturn; -@import _Builtin_tgmath; -@import _Builtin_unwind; -#endif