iana updated this revision to Diff 556630.
iana added a comment.

Actually allow the stdarg module


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159064/new/

https://reviews.llvm.org/D159064

Files:
  clang/lib/Basic/Module.cpp
  clang/lib/Headers/__stddef_max_align_t.h
  clang/lib/Headers/__stddef_null.h
  clang/lib/Headers/__stddef_nullptr_t.h
  clang/lib/Headers/__stddef_offsetof.h
  clang/lib/Headers/__stddef_ptrdiff_t.h
  clang/lib/Headers/__stddef_rsize_t.h
  clang/lib/Headers/__stddef_size_t.h
  clang/lib/Headers/__stddef_unreachable.h
  clang/lib/Headers/__stddef_wchar_t.h
  clang/lib/Headers/__stddef_wint_t.h
  clang/lib/Headers/module.modulemap
  clang/lib/Headers/stdarg.h
  clang/lib/Headers/stddef.h
  clang/test/Headers/stdarg.c
  clang/test/Headers/stdargneeds.c
  clang/test/Headers/stddef.c
  clang/test/Headers/stddefneeds.c
  clang/test/Modules/Inputs/System/usr/include/complex.h
  clang/test/Modules/Inputs/System/usr/include/inttypes.h
  clang/test/Modules/Inputs/System/usr/include/math.h
  clang/test/Modules/Inputs/System/usr/include/module.map
  clang/test/Modules/Inputs/System/usr/include/stdint.h
  clang/test/Modules/compiler_builtins.m
  clang/test/Modules/stddef.c
  clang/test/Modules/stddef.m

Index: clang/test/Modules/stddef.m
===================================================================
--- clang/test/Modules/stddef.m
+++ clang/test/Modules/stddef.m
@@ -4,4 +4,6 @@
 
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I %S/Inputs/StdDef %s -verify
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/StdDef %s -verify
 // expected-no-diagnostics
Index: clang/test/Modules/stddef.c
===================================================================
--- clang/test/Modules/stddef.c
+++ clang/test/Modules/stddef.c
@@ -1,12 +1,22 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify -fno-modules-error-recovery
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fbuiltin-headers-in-system-modules -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify=no-stddef-module -fno-modules-error-recovery
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I%S/Inputs/StdDef %s -verify=yes-stddef-module -fno-modules-error-recovery
 
 #include "ptrdiff_t.h"
 
 ptrdiff_t pdt;
 
-size_t st; // expected-error {{missing '#include "include_again.h"'; 'size_t' must be declared before it is used}}
-// expected-note@__stddef_size_t.h:* {{here}}
+// size_t is declared in both size_t.h and __stddef_size_t.h, both of which are
+// modular headers. Regardless of whether stddef.h joins the StdDef test module
+// or is in its _Builtin_stddef module, __stddef_size_t.h will be in
+// _Builtin_stddef.size_t. It's not defined which module will win as the expected
+// provider of size_t. For the purposes of this test it doesn't matter which header
+// gets reported, just as long as it isn't other.h or include_again.h.
+size_t st; // no-stddef-module-error {{missing '#include "size_t.h"'; 'size_t' must be declared before it is used}} \
+              yes-stddef-module-error {{missing '#include "size_t.h"'; 'size_t' must be declared before it is used}}
+// no-stddef-module-note@size_t.h:* {{here}}
+// yes-stddef-module-note@size_t.h:* {{here}}
 
 #include "include_again.h"
 
Index: clang/test/Modules/compiler_builtins.m
===================================================================
--- clang/test/Modules/compiler_builtins.m
+++ 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 -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
+// 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
 // expected-no-diagnostics
 
 #ifdef __SSE__
@@ -11,3 +11,19 @@
 #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
Index: clang/test/Modules/Inputs/System/usr/include/stdint.h
===================================================================
--- clang/test/Modules/Inputs/System/usr/include/stdint.h
+++ clang/test/Modules/Inputs/System/usr/include/stdint.h
@@ -1 +1,243 @@
 typedef int my_awesome_nonstandard_integer_type;
+
+/* C99 7.18.1.1 Exact-width integer types.
+ * C99 7.18.1.2 Minimum-width integer types.
+ * C99 7.18.1.3 Fastest minimum-width integer types.
+ *
+ * The standard requires that exact-width type be defined for 8-, 16-, 32-, and
+ * 64-bit types if they are implemented. Other exact width types are optional.
+ * This implementation defines an exact-width types for every integer width
+ * that is represented in the standard integer types.
+ *
+ * The standard also requires minimum-width types be defined for 8-, 16-, 32-,
+ * and 64-bit widths regardless of whether there are corresponding exact-width
+ * types.
+ *
+ * To accommodate targets that are missing types that are exactly 8, 16, 32, or
+ * 64 bits wide, this implementation takes an approach of cascading
+ * redefinitions, redefining __int_leastN_t to successively smaller exact-width
+ * types. It is therefore important that the types are defined in order of
+ * descending widths.
+ *
+ * We currently assume that the minimum-width types and the fastest
+ * minimum-width types are the same. This is allowed by the standard, but is
+ * suboptimal.
+ *
+ * In violation of the standard, some targets do not implement a type that is
+ * wide enough to represent all of the required widths (8-, 16-, 32-, 64-bit).
+ * To accommodate these targets, a required minimum-width type is only
+ * defined if there exists an exact-width type of equal or greater width.
+ */
+
+#ifdef __INT64_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+typedef __INT64_TYPE__ int64_t;
+# endif /* __int8_t_defined */
+typedef __UINT64_TYPE__ uint64_t;
+# undef __int_least64_t
+# define __int_least64_t int64_t
+# undef __uint_least64_t
+# define __uint_least64_t uint64_t
+# undef __int_least32_t
+# define __int_least32_t int64_t
+# undef __uint_least32_t
+# define __uint_least32_t uint64_t
+# undef __int_least16_t
+# define __int_least16_t int64_t
+# undef __uint_least16_t
+# define __uint_least16_t uint64_t
+# undef __int_least8_t
+# define __int_least8_t int64_t
+# undef __uint_least8_t
+# define __uint_least8_t uint64_t
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+typedef __int_least64_t int_least64_t;
+typedef __uint_least64_t uint_least64_t;
+typedef __int_least64_t int_fast64_t;
+typedef __uint_least64_t uint_fast64_t;
+#endif /* __int_least64_t */
+
+#ifdef __INT56_TYPE__
+typedef __INT56_TYPE__ int56_t;
+typedef __UINT56_TYPE__ uint56_t;
+typedef int56_t int_least56_t;
+typedef uint56_t uint_least56_t;
+typedef int56_t int_fast56_t;
+typedef uint56_t uint_fast56_t;
+# undef __int_least32_t
+# define __int_least32_t int56_t
+# undef __uint_least32_t
+# define __uint_least32_t uint56_t
+# undef __int_least16_t
+# define __int_least16_t int56_t
+# undef __uint_least16_t
+# define __uint_least16_t uint56_t
+# undef __int_least8_t
+# define __int_least8_t int56_t
+# undef __uint_least8_t
+# define __uint_least8_t uint56_t
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+typedef __INT48_TYPE__ int48_t;
+typedef __UINT48_TYPE__ uint48_t;
+typedef int48_t int_least48_t;
+typedef uint48_t uint_least48_t;
+typedef int48_t int_fast48_t;
+typedef uint48_t uint_fast48_t;
+# undef __int_least32_t
+# define __int_least32_t int48_t
+# undef __uint_least32_t
+# define __uint_least32_t uint48_t
+# undef __int_least16_t
+# define __int_least16_t int48_t
+# undef __uint_least16_t
+# define __uint_least16_t uint48_t
+# undef __int_least8_t
+# define __int_least8_t int48_t
+# undef __uint_least8_t
+# define __uint_least8_t uint48_t
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+typedef __INT40_TYPE__ int40_t;
+typedef __UINT40_TYPE__ uint40_t;
+typedef int40_t int_least40_t;
+typedef uint40_t uint_least40_t;
+typedef int40_t int_fast40_t;
+typedef uint40_t uint_fast40_t;
+# undef __int_least32_t
+# define __int_least32_t int40_t
+# undef __uint_least32_t
+# define __uint_least32_t uint40_t
+# undef __int_least16_t
+# define __int_least16_t int40_t
+# undef __uint_least16_t
+# define __uint_least16_t uint40_t
+# undef __int_least8_t
+# define __int_least8_t int40_t
+# undef __uint_least8_t
+# define __uint_least8_t uint40_t
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+typedef __INT32_TYPE__ int32_t;
+# endif /* __int8_t_defined */
+
+# ifndef __uint32_t_defined  /* more glibc compatibility */
+# define __uint32_t_defined
+typedef __UINT32_TYPE__ uint32_t;
+# endif /* __uint32_t_defined */
+
+# undef __int_least32_t
+# define __int_least32_t int32_t
+# undef __uint_least32_t
+# define __uint_least32_t uint32_t
+# undef __int_least16_t
+# define __int_least16_t int32_t
+# undef __uint_least16_t
+# define __uint_least16_t uint32_t
+# undef __int_least8_t
+# define __int_least8_t int32_t
+# undef __uint_least8_t
+# define __uint_least8_t uint32_t
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+typedef __int_least32_t int_least32_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __int_least32_t int_fast32_t;
+typedef __uint_least32_t uint_fast32_t;
+#endif /* __int_least32_t */
+
+#ifdef __INT24_TYPE__
+typedef __INT24_TYPE__ int24_t;
+typedef __UINT24_TYPE__ uint24_t;
+typedef int24_t int_least24_t;
+typedef uint24_t uint_least24_t;
+typedef int24_t int_fast24_t;
+typedef uint24_t uint_fast24_t;
+# undef __int_least16_t
+# define __int_least16_t int24_t
+# undef __uint_least16_t
+# define __uint_least16_t uint24_t
+# undef __int_least8_t
+# define __int_least8_t int24_t
+# undef __uint_least8_t
+# define __uint_least8_t uint24_t
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+typedef __INT16_TYPE__ int16_t;
+#endif /* __int8_t_defined */
+typedef __UINT16_TYPE__ uint16_t;
+# undef __int_least16_t
+# define __int_least16_t int16_t
+# undef __uint_least16_t
+# define __uint_least16_t uint16_t
+# undef __int_least8_t
+# define __int_least8_t int16_t
+# undef __uint_least8_t
+# define __uint_least8_t uint16_t
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+typedef __int_least16_t int_least16_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __int_least16_t int_fast16_t;
+typedef __uint_least16_t uint_fast16_t;
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+#ifndef __int8_t_defined  /* glibc sys/types.h also defines int8_t*/
+typedef __INT8_TYPE__ int8_t;
+#endif /* __int8_t_defined */
+typedef __UINT8_TYPE__ uint8_t;
+# undef __int_least8_t
+# define __int_least8_t int8_t
+# undef __uint_least8_t
+# define __uint_least8_t uint8_t
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+typedef __int_least8_t int_least8_t;
+typedef __uint_least8_t uint_least8_t;
+typedef __int_least8_t int_fast8_t;
+typedef __uint_least8_t uint_fast8_t;
+#endif /* __int_least8_t */
+
+/* prevent glibc sys/types.h from defining conflicting types */
+#ifndef __int8_t_defined
+# define __int8_t_defined
+#endif /* __int8_t_defined */
+
+/* C99 7.18.1.4 Integer types capable of holding object pointers.
+ */
+#define __stdint_join3(a,b,c) a ## b ## c
+
+#ifndef _INTPTR_T
+#ifndef __intptr_t_defined
+typedef __INTPTR_TYPE__ intptr_t;
+#define __intptr_t_defined
+#define _INTPTR_T
+#endif
+#endif
+
+#ifndef _UINTPTR_T
+typedef __UINTPTR_TYPE__ uintptr_t;
+#define _UINTPTR_T
+#endif
+
+/* C99 7.18.1.5 Greatest-width integer types.
+ */
+typedef __INTMAX_TYPE__  intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
Index: clang/test/Modules/Inputs/System/usr/include/module.map
===================================================================
--- clang/test/Modules/Inputs/System/usr/include/module.map
+++ clang/test/Modules/Inputs/System/usr/include/module.map
@@ -1,9 +1,24 @@
 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"
Index: clang/test/Headers/stddefneeds.c
===================================================================
--- clang/test/Headers/stddefneeds.c
+++ clang/test/Headers/stddefneeds.c
@@ -1,36 +1,72 @@
+// RUN: rm -fR %t
 // RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s
 // RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %s
 
 // Use C99 to verify that __need_ can be used to get types that wouldn't normally be available.
 
 struct astruct { char member; };
 
-ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c23-error{{unknown type}}
-size_t s0; // c99-error{{unknown type name 'size_t'}} c23-error{{unknown type}}
-rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c23-error{{unknown type}}
-wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c23-error{{unknown type}}
-void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c23-error{{undeclared identifier}}
-nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c23-error{{unknown type}}
-static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c23-error{{undeclared identifier 'unreachable'}}
-max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c23-error{{unknown type}}
+ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+size_t s0; // c99-error{{unknown type name 'size_t'}} c23-error{{unknown type}} \
+              c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c23-error{{unknown type}} \
+                c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c23-error{{undeclared identifier}} \
+                    c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c23-error{{undeclared identifier 'unreachable'}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
+max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c23-error{{unknown type}} \
+                   c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 size_t o0 = offsetof(struct astruct, member); // c99-error{{unknown type name 'size_t'}} c99-error{{call to undeclared function 'offsetof'}} c99-error{{expected expression}} c99-error{{use of undeclared identifier 'member'}} \
-                                                 c23-error{{unknown type name 'size_t'}} c23-error{{undeclared identifier 'offsetof'}} c23-error{{expected expression}} c23-error{{use of undeclared identifier 'member'}}
-wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c23-error{{unknown type}}
+                                                 c23-error{{unknown type name 'size_t'}} c23-error{{undeclared identifier 'offsetof'}} c23-error{{expected expression}} c23-error{{use of undeclared identifier 'member'}} \
+                                                 c99-modules-error{{unknown type}} c99-modules-error{{undeclared function}} c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{unknown type}} c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_ptrdiff_t
 #include <stddef.h>
 
 ptrdiff_t p1;
-size_t s1; // c99-error{{unknown type}} c23-error{{unknown type}}
-rsize_t r1; // c99-error{{unknown type}} c23-error{{unknown type}}
-wchar_t wc1; // c99-error{{unknown type}} c23-error{{unknown type}}
-void *v1 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
-nullptr_t n1; // c99-error{{unknown type}} c23-error{{unknown type}}
-static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
-max_align_t m1; // c99-error{{unknown type}} c23-error{{unknown type}}
+size_t s1; // c99-error{{unknown type}} c23-error{{unknown type}} \
+              c99-modules-error{{'size_t' must be declared before it is used}} c23-modules-error{{must be declared}} \
+              c99-modules-note@__stddef_size_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_size_t.h:*{{declaration here is not visible}}
+rsize_t r1; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{'rsize_t' must be declared before it is used}} c23-modules-error{{must be declared}} \
+               c99-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}}
+wchar_t wc1; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                c99-modules-error{{'wchar_t' must be declared before it is used}} c23-modules-error{{must be declared}} \
+                c99-modules-note@__stddef_wchar_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_wchar_t.h:*{{declaration here is not visible}}
+void *v1 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \
+                    c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+nullptr_t n1; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c23-modules-error{{'nullptr_t' must be declared before it is used}} \
+                 c23-modules-note@__stddef_nullptr_t.h:*{{declaration here is not visible}}
+static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
+max_align_t m1; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                   c99-modules-error{{'max_align_t' must be declared before it is used}} c23-modules-error{{must be declared}} \
+                   c99-modules-note@__stddef_max_align_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_max_align_t.h:*{{declaration here is not visible}}
 size_t o1 = offsetof(struct astruct, member); // c99-error{{unknown type}} c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi1; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi1; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+
+// The "must be declared before used" errors are only emitted the first time a
+// known-but-not-visible type is seen. At this point the _Builtin_stddef module
+// has been built and all of the types tried, so most of the errors won't be
+// repeated below in modules. The types still aren't available, just the errors
+// aren't repeated. e.g. rsize_t still isn't available, if r1 above got deleted,
+// its error would move to r2 below.
 
 #define __need_size_t
 #include <stddef.h>
@@ -40,13 +76,19 @@
 rsize_t r2; // c99-error{{unknown type}} c23-error{{unknown type}}
             // c99-note@__stddef_size_t.h:*{{'size_t' declared here}} c23-note@__stddef_size_t.h:*{{'size_t' declared here}}
 wchar_t wc2; // c99-error{{unknown type}} c23-error{{unknown type}}
-void *v2 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
-nullptr_t n2; // c99-error{{unknown type}} c23-error{{unknown type}}
-static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
+void *v2 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \
+                    c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+nullptr_t n2; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}}
+static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
 max_align_t m2; // c99-error{{unknown type}} c23-error{{unknown type}}
 size_t o2 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi2; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi2; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_rsize_t
 #include <stddef.h>
@@ -55,13 +97,19 @@
 size_t s3;
 rsize_t r3;
 wchar_t wc3; // c99-error{{unknown type}} c23-error{{unknown type}}
-void *v3 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
-nullptr_t n3; // c99-error{{unknown type}} c23-error{{unknown type}}
-static void f3(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
+void *v3 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \
+                    c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+nullptr_t n3; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}}
+static void f3(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
 max_align_t m3; // c99-error{{unknown type}} c23-error{{unknown type}}
 size_t o3 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi3; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi3; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_wchar_t
 #include <stddef.h>
@@ -70,13 +118,19 @@
 size_t s4;
 rsize_t r4;
 wchar_t wc4;
-void *v4 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}}
-nullptr_t n4; // c99-error{{unknown type}} c23-error{{unknown type}}
-static void f4(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
+void *v4 = NULL; // c99-error{{undeclared identifier}} c23-error{{undeclared identifier}} \
+                    c99-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+nullptr_t n4; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}}
+static void f4(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
 max_align_t m4; // c99-error{{unknown type}} c23-error{{unknown type}}
 size_t o4 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi4; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi4; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_NULL
 #include <stddef.h>
@@ -86,29 +140,38 @@
 rsize_t r5;
 wchar_t wc5;
 void *v5 = NULL;
-nullptr_t n5; // c99-error{{unknown type}} c23-error{{unknown type}}
-static void f5(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
+nullptr_t n5; // c99-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}}
+static void f5(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
 max_align_t m5; // c99-error{{unknown type}} c23-error{{unknown type}}
 size_t o5 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi5; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi5; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
-// __need_nullptr_t generates an error in <C23 because its definition
+// nullptr_t doesn't get declared before C23 because its definition
 // depends on nullptr.
 #define __need_nullptr_t
-#include <stddef.h> // c99-error@__stddef_nullptr_t.h:*{{expected function body}}
+#include <stddef.h>
 
 ptrdiff_t p6;
 size_t s6;
 rsize_t r6;
 wchar_t wc6;
 void *v6 = NULL;
-nullptr_t n6; // c99-error{{unknown type}}
-static void f6(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}}
+nullptr_t n6; // c99-error{{unknown type}} c99-modules-error{{unknown type}}
+static void f6(void) { unreachable(); } // c99-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
 max_align_t m6; // c99-error{{unknown type}} c23-error{{unknown type}}
 size_t o6 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi6; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi6; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_unreachable
 #include <stddef.h>
@@ -118,12 +181,15 @@
 rsize_t r7;
 wchar_t wc7;
 void *v7 = NULL;
-nullptr_t n7 ; // c99-error{{unknown type}}
+nullptr_t n7 ; // c99-error{{unknown type}} c99-modules-error{{unknown type}}
 static void f7(void) { unreachable(); }
 max_align_t m7; // c99-error{{unknown type}} c23-error{{unknown type}}
 size_t o7 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi7; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi7; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_max_align_t
 #include <stddef.h>
@@ -133,12 +199,15 @@
 rsize_t r8;
 wchar_t wc8;
 void *v8 = NULL;
-nullptr_t n8; // c99-error{{unknown type}}
+nullptr_t n8; // c99-error{{unknown type}} c99-modules-error{{unknown type}}
 static void f8(void) { unreachable(); }
 max_align_t m8;
 size_t o8 = offsetof(struct astruct, member); // c99-error{{expected expression}} c99-error{{undeclared identifier}} \
-                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi8; // c99-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi8; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_offsetof
 #include <stddef.h>
@@ -146,13 +215,14 @@
 ptrdiff_t p9;
 size_t s9;
 rsize_t r9;
-nullptr_t n9; // c99-error{{unknown type}}
+nullptr_t n9; // c99-error{{unknown type}} c99-modules-error{{unknown type}}
 static void f9(void) { unreachable(); }
 wchar_t wc9;
 void *v9 = NULL;
 max_align_t m9;
 size_t o9 = offsetof(struct astruct, member);
-wint_t wi9; // c99-error{{unknown type}} c23-error{{unknown type}}
+wint_t wi9; // c99-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #define __need_wint_t
 #include <stddef.h>
@@ -162,7 +232,7 @@
 rsize_t r10;
 wchar_t wc10;
 void *v10 = NULL;
-nullptr_t n10; // c99-error{{unknown type}}
+nullptr_t n10; // c99-error{{unknown type}} c99-modules-error{{unknown type}}
 static void f10(void) { unreachable(); }
 max_align_t m10;
 size_t o10 = offsetof(struct astruct, member);
Index: clang/test/Headers/stddef.c
===================================================================
--- clang/test/Headers/stddef.c
+++ clang/test/Headers/stddef.c
@@ -1,35 +1,57 @@
+// RUN: rm -fR %t
 // RUN: %clang_cc1 -fsyntax-only -verify=c99 -std=c99 %s
 // RUN: %clang_cc1 -fsyntax-only -verify=c11 -std=c11 %s
 // RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c99 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c11-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c23-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -std=c23 %s
 
 struct astruct { char member; };
 
-ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
-size_t s0; // c99-error{{unknown type name 'size_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
-rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
-wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
-void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c11-error{{undeclared identifier}} c23-error{{undeclared identifier}}
-nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
-static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c11-error{{undeclared function}} c23-error{{undeclared identifier}}
-max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
+ptrdiff_t p0; // c99-error{{unknown type name 'ptrdiff_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+size_t s0; // c99-error{{unknown type name 'size_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+              c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+rsize_t r0; // c99-error{{unknown type name 'rsize_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+wchar_t wc0; // c99-error{{unknown type name 'wchar_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+                c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+void *v0 = NULL; // c99-error{{use of undeclared identifier 'NULL'}} c11-error{{undeclared identifier}} c23-error{{undeclared identifier}} \
+                    c99-modules-error{{undeclared identifier}} c11-modules-error{{undeclared identifier}} c23-modules-error{{undeclared identifier}}
+nullptr_t n0; // c99-error{{unknown type name 'nullptr_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+static void f0(void) { unreachable(); } // c99-error{{call to undeclared function 'unreachable'}} c11-error{{undeclared function}} c23-error{{undeclared identifier}} \
+                                           c99-modules-error{{undeclared function}} c11-modules-error{{undeclared function}} c23-modules-error{{undeclared identifier}}
+max_align_t m0; // c99-error{{unknown type name 'max_align_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+                   c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 size_t o0 = offsetof(struct astruct, member); // c99-error{{unknown type name 'size_t'}} c99-error{{call to undeclared function 'offsetof'}} c99-error{{expected expression}} c99-error{{use of undeclared identifier 'member'}} \
                                                  c11-error{{unknown type}} c11-error{{undeclared function}} c11-error{{expected expression}} c11-error{{undeclared identifier}} \
-                                                 c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}}
-wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c11-error{{unknown type}} c23-error{{unknown type}}
+                                                 c23-error{{unknown type}} c23-error{{undeclared identifier}} c23-error{{expected expression}} c23-error{{undeclared identifier}} \
+                                                 c99-modules-error{{unknown type}} c99-modules-error{{undeclared function}} c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}} \
+                                                 c11-modules-error{{unknown type}} c11-modules-error{{undeclared function}} c11-modules-error{{expected expression}} c11-modules-error{{undeclared identifier}} \
+                                                 c23-modules-error{{unknown type}} c23-modules-error{{undeclared identifier}} c23-modules-error{{expected expression}} c23-modules-error{{undeclared identifier}}
+wint_t wi0; // c99-error{{unknown type name 'wint_t'}} c11-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type name 'wint_t'}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 #include <stddef.h>
 
 ptrdiff_t p1;
 size_t s1;
-rsize_t r1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
-            // c99-note@__stddef_size_t.h:*{{'size_t' declared here}} c11-note@__stddef_size_t.h:*{{'size_t' declared here}} c23-note@__stddef_size_t.h:*{{'size_t' declared here}}
+rsize_t r1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} \
+               c99-note@__stddef_size_t.h:*{{'size_t' declared here}} c11-note@__stddef_size_t.h:*{{'size_t' declared here}} c23-note@__stddef_size_t.h:*{{'size_t' declared here}} \
+               c99-modules-error{{'rsize_t' must be declared before it is used}} c11-modules-error{{must be declared}} c23-modules-error{{must be declared}} \
+               c99-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} c11-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_rsize_t.h:*{{declaration here is not visible}}
 wchar_t wc1;
 void *v1 = NULL;
-nullptr_t n1; // c99-error{{unknown type}} c11-error{{unknown type}}
-static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}}
-max_align_t m1; // c99-error{{unknown type}}
+nullptr_t n1; // c99-error{{unknown type}} c11-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c11-modules-error{{unknown type}}
+static void f1(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}} \
+                                           c99-modules-error{{undeclared function}} c11-modules-error{{undeclared function}}
+max_align_t m1; // c99-error{{unknown type}} c99-modules-error{{'max_align_t' must be declared before it is used}} \
+                   c99-modules-note@__stddef_max_align_t.h:*{{declaration here is not visible}}
 size_t o1 = offsetof(struct astruct, member);
-wint_t wi1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
+wint_t wi1; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
 
 // rsize_t needs to be opted into via __STDC_WANT_LIB_EXT1__ >= 1.
 #define __STDC_WANT_LIB_EXT1__ 1
@@ -39,8 +61,14 @@
 rsize_t r2;
 wchar_t wc2;
 void *v2 = NULL;
-nullptr_t n2; // c99-error{{unknown type}} c11-error{{unknown type}}
-static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}}
+nullptr_t n2; // c99-error{{unknown type}} c11-error{{unknown type}} \
+                 c99-modules-error{{unknown type}} c11-modules-error{{unknown type}}
+static void f2(void) { unreachable(); } // c99-error{{undeclared function}} c11-error{{undeclared function}} \
+                                           c99-modules-error{{undeclared function}} c11-modules-error{{undeclared function}}
 max_align_t m2; // c99-error{{unknown type}}
 size_t o2 = offsetof(struct astruct, member);
-wint_t wi2; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}}
+wint_t wi2; // c99-error{{unknown type}} c11-error{{unknown type}} c23-error{{unknown type}} \
+               c99-modules-error{{unknown type}} c11-modules-error{{unknown type}} c23-modules-error{{unknown type}}
+
+// m2 and wi2 don't generate errors in modules, the "must be declared before used"
+// errors are only emitted the first time the known-but-not-visible type is seen.
Index: clang/test/Headers/stdargneeds.c
===================================================================
--- clang/test/Headers/stdargneeds.c
+++ clang/test/Headers/stdargneeds.c
@@ -1,23 +1,35 @@
+// RUN: rm -fR %t
 // RUN: split-file %s %t
 // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds0.c
 // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds1.c
+// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds1.c
 // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds2.c
+// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds2.c
 // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds3.c
+// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds3.c
 // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds4.c
+// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds4.c
 // RUN: %clang_cc1 -fsyntax-only -verify -Werror=implicit-function-declaration -std=c89 %t/stdargneeds5.c
+// RUN: %clang_cc1 -fsyntax-only -verify=expected-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdargneeds5.c
 
 // Split the file so that the "implicitly declaring library function" errors get repeated.
 // Use C89 to verify that __need_ can be used to get types that wouldn't normally be available.
 
 //--- stdargneeds0.c
 static void f(int p, ...) {
-    __gnuc_va_list g; // expected-error{{undeclared identifier '__gnuc_va_list'}}
-    va_list v; // expected-error{{undeclared identifier 'va_list'}}
-    va_start(v, p); // expected-error{{implicitly declaring library function 'va_start'}} expected-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_start'}} expected-error{{undeclared identifier 'v'}}
-    int i = va_arg(v, int); // expected-error{{implicit declaration of function 'va_arg'}} expected-error{{expected expression}} expected-error{{use of undeclared identifier 'v'}}
-    va_end(v); // expected-error{{implicitly declaring library function 'va_end'}} expected-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_end'}} expected-error{{undeclared identifier 'v'}}
-    __va_copy(g, v); // expected-error{{implicit declaration of function '__va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}}
-    va_copy(g, v); // expected-error{{implicitly declaring library function 'va_copy'}} expected-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}}
+    __gnuc_va_list g; // expected-error{{undeclared identifier '__gnuc_va_list'}} expected-modules-error{{undeclared identifier}}
+    va_list v; // expected-error{{undeclared identifier 'va_list'}} expected-modules-error{{undeclared identifier}}
+    va_start(v, p); // expected-error{{implicitly declaring library function 'va_start'}} expected-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_start'}} expected-error{{undeclared identifier 'v'}} \
+                       expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} expected-modules-error{{undeclared identifier}}
+    int i = va_arg(v, int); // expected-error{{implicit declaration of function 'va_arg'}} expected-error{{expected expression}} expected-error{{use of undeclared identifier 'v'}} \
+                               expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}} expected-modules-error{{undeclared identifier}}
+    va_end(v); // expected-error{{implicitly declaring library function 'va_end'}} expected-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_end'}} expected-error{{undeclared identifier 'v'}} \
+                  expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} expected-modules-error{{undeclared identifier}}
+    __va_copy(g, v); // expected-error{{implicit declaration of function '__va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}} \
+                        expected-modules-error{{implicit declaration of function}} expected-modules-error{{undeclared identifier}} expected-modules-error{{undeclared identifier}}
+    va_copy(g, v); // expected-error{{implicitly declaring library function 'va_copy'}} expected-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_copy'}} expected-error{{use of undeclared identifier 'g'}} expected-error{{use of undeclared identifier 'v'}} \
+                      expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}} expected-modules-error{{undeclared identifier}} expected-modules-error{{undeclared identifier}}
 }
 
 //--- stdargneeds1.c
@@ -25,25 +37,37 @@
 #include <stdarg.h>
 static void f(int p, ...) {
     __gnuc_va_list g;
-    va_list v; // expected-error{{undeclared identifier}}
-    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}}
-    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} expected-error{{undeclared identifier}}
-    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}}
-    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}}
-    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}}
+    va_list v; // expected-error{{undeclared identifier}} \
+                  expected-modules-error{{'va_list' must be declared before it is used}} expected-modules-note@__stdarg_va_list.h:*{{declaration here is not visible}}
+    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \
+                       expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} expected-error{{undeclared identifier}} \
+                               expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}}
+    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \
+                  expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} \
+                        expected-modules-error{{implicit declaration of function}}
+    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \
+                      expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
 }
 
 //--- stdargneeds2.c
 #define __need_va_list
 #include <stdarg.h>
 static void f(int p, ...) {
-    __gnuc_va_list g; // expected-error{{undeclared identifier}}
+    __gnuc_va_list g; // expected-error{{undeclared identifier}} \
+                         expected-modules-error{{'__gnuc_va_list' must be declared before it is used}} expected-modules-note@__stdarg___gnuc_va_list.h:*{{declaration here is not visible}}
     va_list v;
-    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
-    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}}
-    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
-    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}}
-    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}}
+    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                       expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} \
+                               expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}}
+    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                  expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} \
+                        expected-modules-error{{implicit declaration of function}}
+    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \
+                      expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
 }
 
 //--- stdargneeds3.c
@@ -51,13 +75,16 @@
 #define __need_va_arg
 #include <stdarg.h>
 static void f(int p, ...) {
-    __gnuc_va_list g; // expected-error{{undeclared identifier}}
+    __gnuc_va_list g; // expected-error{{undeclared identifier}} \
+                         expected-modules-error{{'__gnuc_va_list' must be declared before it is used}} expected-modules-note@__stdarg___gnuc_va_list.h:*{{declaration here is not visible}}
     va_list v;
     va_start(v, p);
     int i = va_arg(v, int);
     va_end(v);
-    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}}
-    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}}
+    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-error{{undeclared identifier}} \
+                        expected-modules-error{{implicit declaration of function}}
+    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} expected-error{{undeclared identifier}} \
+                      expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
 }
 
 //--- stdargneeds4.c
@@ -68,11 +95,15 @@
 static void f(int p, ...) {
     __gnuc_va_list g;
     va_list v;
-    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
-    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}}
-    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
+    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                       expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} \
+                               expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}}
+    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                  expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
     __va_copy(g, v);
-    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
+    va_copy(g, v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                      expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
 }
 
 //--- stdargneeds5.c
@@ -83,9 +114,12 @@
 static void f(int p, ...) {
     __gnuc_va_list g;
     va_list v;
-    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
-    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}}
-    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}}
-    __va_copy(g, v); // expected-error{{implicit declaration of function}}
+    va_start(v, p); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                       expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    int i = va_arg(v, int); // expected-error{{implicit declaration of function}} expected-error{{expected expression}} \
+                               expected-modules-error{{implicit declaration of function}} expected-modules-error{{expected expression}}
+    va_end(v); // expected-error{{implicitly declaring library function}} expected-note{{provide a declaration}} \
+                  expected-modules-error{{implicitly declaring library function}} expected-modules-note{{provide a declaration}}
+    __va_copy(g, v); // expected-error{{implicit declaration of function}} expected-modules-error{{implicit declaration of function}}
     va_copy(g, v);
 }
Index: clang/test/Headers/stdarg.c
===================================================================
--- clang/test/Headers/stdarg.c
+++ clang/test/Headers/stdarg.c
@@ -1,29 +1,47 @@
+// RUN: rm -fR %t
 // RUN: split-file %s %t
 // RUN: %clang_cc1 -fsyntax-only -verify=c89 -Werror=implicit-function-declaration -std=c89 %t/stdarg0.c
 // RUN: %clang_cc1 -fsyntax-only -verify=c99 -Werror=implicit-function-declaration -std=c99 %t/stdarg0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c89-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdarg0.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c99 %t/stdarg0.c
 // RUN: %clang_cc1 -fsyntax-only -verify=c89 -Werror=implicit-function-declaration -std=c89 %t/stdarg1.c
 // RUN: %clang_cc1 -fsyntax-only -verify=c99 -Werror=implicit-function-declaration -std=c99 %t/stdarg1.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c89-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c89 %t/stdarg1.c
+// RUN: %clang_cc1 -fsyntax-only -verify=c99-modules -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=implicit-function-declaration -std=c99 %t/stdarg1.c
 
 // Split the file so that the "implicitly declaring library function" errors get repeated.
 
 //--- stdarg0.c
 static void f(int p, ...) {
-    __gnuc_va_list g; // c89-error{{undeclared identifier '__gnuc_va_list'}} c99-error{{undeclared identifier}}
-    va_list v; // c89-error{{undeclared identifier 'va_list'}} c99-error{{undeclared identifier}}
+    __gnuc_va_list g; // c89-error{{undeclared identifier '__gnuc_va_list'}} c99-error{{undeclared identifier}} \
+                         c89-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}}
+    va_list v; // c89-error{{undeclared identifier 'va_list'}} c99-error{{undeclared identifier}} \
+                  c89-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}}
     va_start(v, p); // c89-error{{implicitly declaring library function 'va_start'}} c89-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_start'}} c89-error{{undeclared identifier 'v'}} \
-                       c99-error{{call to undeclared library function 'va_start'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}}
+                       c99-error{{call to undeclared library function 'va_start'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} \
+                       c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} c89-modules-error{{undeclared identifier}} \
+                       c99-modules-error{{undeclared library function}} c99-modules-note{{provide a declaration}} c99-modules-error{{undeclared identifier}}
     int i = va_arg(v, int); // c89-error{{implicit declaration of function 'va_arg'}} c89-error{{expected expression}} c89-error{{use of undeclared identifier 'v'}} \
-                               c99-error{{call to undeclared function 'va_arg'}} c99-error{{expected expression}} c99-error{{undeclared identifier}}
+                               c99-error{{call to undeclared function 'va_arg'}} c99-error{{expected expression}} c99-error{{undeclared identifier}} \
+                               c89-modules-error{{implicit declaration of function}} c89-modules-error{{expected expression}} c89-modules-error{{undeclared identifier}} \
+                               c99-modules-error{{undeclared function}} c99-modules-error{{expected expression}} c99-modules-error{{undeclared identifier}}
     va_end(v); // c89-error{{implicitly declaring library function 'va_end'}} c89-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_end'}} c89-error{{undeclared identifier 'v'}} \
-                  c99-error{{call to undeclared library function 'va_end'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}}
+                  c99-error{{call to undeclared library function 'va_end'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} \
+                  c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} c89-modules-error{{undeclared identifier}} \
+                  c99-modules-error{{undeclared library function}} c99-modules-note{{provide a declaration}} c99-modules-error{{undeclared identifier}}
     __va_copy(g, v); // c89-error{{implicit declaration of function '__va_copy'}} c89-error{{use of undeclared identifier 'g'}} c89-error{{use of undeclared identifier 'v'}} \
-                        c99-error{{call to undeclared function '__va_copy'}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}}
+                        c99-error{{call to undeclared function '__va_copy'}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}} \
+                        c89-modules-error{{implicit declaration of function}} c89-modules-error{{undeclared identifier}} c89-modules-error{{undeclared identifier}} \
+                        c99-modules-error{{undeclared function}} c99-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}}
     va_copy(g, v); // c89-error{{implicitly declaring library function 'va_copy'}} c89-note{{include the header <stdarg.h> or explicitly provide a declaration for 'va_copy'}} c89-error{{use of undeclared identifier 'g'}} c89-error{{use of undeclared identifier 'v'}} \
-                      c99-error{{call to undeclared library function 'va_copy'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}}
+                      c99-error{{call to undeclared library function 'va_copy'}} c99-note{{provide a declaration}} c99-error{{undeclared identifier}} c99-error{{undeclared identifier}} \
+                      c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}} c89-modules-error{{undeclared identifier}} c89-modules-error{{undeclared identifier}} \
+                      c99-modules-error{{undeclared library function}} c99-modules-note{{provide a declaration}} c99-modules-error{{undeclared identifier}} c99-modules-error{{undeclared identifier}}
 }
 
 //--- stdarg1.c
 // c99-no-diagnostics
+// c99-modules-no-diagnostics
 
 #include <stdarg.h>
 static void f(int p, ...) {
@@ -33,5 +51,6 @@
     int i = va_arg(v, int);
     va_end(v);
     __va_copy(g, v);
-    va_copy(g, v); // c89-error{{implicitly declaring library function}} c89-note{{provide a declaration}}
+    va_copy(g, v); // c89-error{{implicitly declaring library function}} c89-note{{provide a declaration}} \
+                      c89-modules-error{{implicitly declaring library function}} c89-modules-note{{provide a declaration}}
 }
Index: clang/lib/Headers/stddef.h
===================================================================
--- clang/lib/Headers/stddef.h
+++ clang/lib/Headers/stddef.h
@@ -7,23 +7,41 @@
  *===-----------------------------------------------------------------------===
  */
 
-#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) ||                       \
-    defined(__need_size_t) || defined(__need_rsize_t) ||                       \
-    defined(__need_wchar_t) || defined(__need_NULL) ||                         \
-    defined(__need_nullptr_t) || defined(__need_unreachable) ||                \
-    defined(__need_max_align_t) || defined(__need_offsetof) ||                 \
-    defined(__need_wint_t) ||                                                  \
-    (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1)
+/*
+ * 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 stddef.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 stddef.h
+ * When SM.A builds, __STDDEF_H will be defined. When SM.B builds, the
+ * definition from SM.A will leak when building without local submodule
+ * visibility. stddef.h wouldn't include any of its implementation headers, and
+ * SM.B wouldn't import any of the stddef modules, and SM.B's `export *`
+ * wouldn't export any stddef interfaces as expected. However, since stddef.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(__STDDEF_H) || __has_feature(modules) ||                          \
+    (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1) ||        \
+    defined(__need_ptrdiff_t) || defined(__need_size_t) ||                     \
+    defined(__need_rsize_t) || defined(__need_wchar_t) ||                      \
+    defined(__need_NULL) || defined(__need_nullptr_t) ||                       \
+    defined(__need_unreachable) || defined(__need_max_align_t) ||              \
+    defined(__need_offsetof) || defined(__need_wint_t)
 
 #if !defined(__need_ptrdiff_t) && !defined(__need_size_t) &&                   \
     !defined(__need_rsize_t) && !defined(__need_wchar_t) &&                    \
     !defined(__need_NULL) && !defined(__need_nullptr_t) &&                     \
     !defined(__need_unreachable) && !defined(__need_max_align_t) &&            \
     !defined(__need_offsetof) && !defined(__need_wint_t)
-/* Always define miscellaneous pieces when modules are available. */
-#if !__has_feature(modules)
 #define __STDDEF_H
-#endif
 #define __need_ptrdiff_t
 #define __need_size_t
 /* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
Index: clang/lib/Headers/stdarg.h
===================================================================
--- clang/lib/Headers/stdarg.h
+++ clang/lib/Headers/stdarg.h
@@ -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) &&                   \
Index: clang/lib/Headers/module.modulemap
===================================================================
--- clang/lib/Headers/module.modulemap
+++ clang/lib/Headers/module.modulemap
@@ -153,9 +153,164 @@
   }
 }
 
-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
Index: clang/lib/Headers/__stddef_wint_t.h
===================================================================
--- clang/lib/Headers/__stddef_wint_t.h
+++ clang/lib/Headers/__stddef_wint_t.h
@@ -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
Index: clang/lib/Headers/__stddef_wchar_t.h
===================================================================
--- clang/lib/Headers/__stddef_wchar_t.h
+++ clang/lib/Headers/__stddef_wchar_t.h
@@ -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
Index: clang/lib/Headers/__stddef_unreachable.h
===================================================================
--- clang/lib/Headers/__stddef_unreachable.h
+++ clang/lib/Headers/__stddef_unreachable.h
@@ -7,7 +7,6 @@
  *===-----------------------------------------------------------------------===
  */
 
-#if !defined(unreachable) || __has_feature(modules)
-/* Always define unreachable when modules are available. */
+#ifndef unreachable
 #define unreachable() __builtin_unreachable()
 #endif
Index: clang/lib/Headers/__stddef_size_t.h
===================================================================
--- clang/lib/Headers/__stddef_size_t.h
+++ clang/lib/Headers/__stddef_size_t.h
@@ -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
Index: clang/lib/Headers/__stddef_rsize_t.h
===================================================================
--- clang/lib/Headers/__stddef_rsize_t.h
+++ clang/lib/Headers/__stddef_rsize_t.h
@@ -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
Index: clang/lib/Headers/__stddef_ptrdiff_t.h
===================================================================
--- clang/lib/Headers/__stddef_ptrdiff_t.h
+++ clang/lib/Headers/__stddef_ptrdiff_t.h
@@ -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
Index: clang/lib/Headers/__stddef_offsetof.h
===================================================================
--- clang/lib/Headers/__stddef_offsetof.h
+++ clang/lib/Headers/__stddef_offsetof.h
@@ -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
Index: clang/lib/Headers/__stddef_nullptr_t.h
===================================================================
--- clang/lib/Headers/__stddef_nullptr_t.h
+++ clang/lib/Headers/__stddef_nullptr_t.h
@@ -7,11 +7,9 @@
  *===-----------------------------------------------------------------------===
  */
 
-#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 {
@@ -19,7 +17,8 @@
 }
 using ::std::nullptr_t;
 #endif
-#else
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
 typedef typeof(nullptr) nullptr_t;
 #endif
+
 #endif
Index: clang/lib/Headers/__stddef_null.h
===================================================================
--- clang/lib/Headers/__stddef_null.h
+++ clang/lib/Headers/__stddef_null.h
@@ -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
@@ -17,3 +25,5 @@
 #else
 #define NULL ((void*)0)
 #endif
+
+#endif
Index: clang/lib/Headers/__stddef_max_align_t.h
===================================================================
--- clang/lib/Headers/__stddef_max_align_t.h
+++ clang/lib/Headers/__stddef_max_align_t.h
@@ -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.
Index: clang/lib/Basic/Module.cpp
===================================================================
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -299,8 +299,9 @@
     if (Requested->isSubModuleOf(Use))
       return true;
 
-  // Anyone is allowed to use our builtin stddef.h and its accompanying module.
-  if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
+  // 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"))
     return true;
 
   if (NoUndeclaredIncludes)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to