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

Rebase


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_null.h
  clang/lib/Headers/__stddef_nullptr_t.h
  clang/lib/Headers/module.modulemap
  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,5 @@
 
 // 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: %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,23 @@
 // 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: %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}}
+// When builtin headers join system modules, stddef.h and its sub-headers have no
+// header guards, and so are seen last by include_again.h, which takes all of their
+// declarations including size_t even though size_t.h previously declared it.
+// When builtin headers don't join the system modules and instead get their own
+// modules, none of the stddef.h declarations go in the StdDef test module. size_t
+// is then declared in both StdDef.SizeT and _Builtin_stddef.size_t. For the
+// purposes of this test it doesn't matter which one gets reported, just as long
+// as it isn't other.h or include_again.h.
+size_t st; // no-stddef-module-error {{missing '#include "include_again.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@__stddef_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,73 @@
+// 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{{'wint_t' must be declared before it is used}} c23-modules-error{{must be declared}} \
+               c99-modules-note@__stddef_wint_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_wint_t.h:*{{declaration here is not visible}}
+
+// 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,12 +77,17 @@
 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}}
+                                                 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}}
 
 #define __need_rsize_t
@@ -55,12 +97,17 @@
 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}}
+                                                 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}}
 
 #define __need_wchar_t
@@ -70,12 +117,17 @@
 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}}
+                                                 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}}
 
 #define __need_NULL
@@ -86,28 +138,35 @@
 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}}
+                                                 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}}
 
-// __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}}
+                                                 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}}
 
 #define __need_unreachable
@@ -118,11 +177,13 @@
 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}}
+                                                 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}}
 
 #define __need_max_align_t
@@ -133,11 +194,13 @@
 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}}
+                                                 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}}
 
 #define __need_offsetof
@@ -146,7 +209,7 @@
 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;
@@ -162,7 +225,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{{'wint_t' must be declared before it is used}} c11-modules-error{{must be declared}} c23-modules-error{{must be declared}}
 
 // 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-note@__stddef_wint_t.h:*{{declaration here is not visible}} c11-modules-note@__stddef_wint_t.h:*{{declaration here is not visible}} c23-modules-note@__stddef_wint_t.h:*{{declaration here is not visible}}
+
+// 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/module.modulemap
===================================================================
--- clang/lib/Headers/module.modulemap
+++ clang/lib/Headers/module.modulemap
@@ -153,8 +153,142 @@
   }
 }
 
-module _Builtin_stddef_max_align_t [system] [extern_c] {
-  header "__stddef_max_align_t.h"
+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 *
+}
+
+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 *
+  }
+
+  explicit module wint_t {
+    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 *
 }
 
 module opencl_c {
Index: clang/lib/Headers/__stddef_nullptr_t.h
===================================================================
--- clang/lib/Headers/__stddef_nullptr_t.h
+++ clang/lib/Headers/__stddef_nullptr_t.h
@@ -18,7 +18,7 @@
 }
 using ::std::nullptr_t;
 #endif
-#else
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
 typedef typeof(nullptr) nullptr_t;
 #endif
 
Index: clang/lib/Headers/__stddef_null.h
===================================================================
--- clang/lib/Headers/__stddef_null.h
+++ clang/lib/Headers/__stddef_null.h
@@ -7,7 +7,16 @@
  *===-----------------------------------------------------------------------===
  */
 
+#if !defined(NULL) || __has_feature(builtin_headers_in_system_modules) ||      \
+    !__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 +26,5 @@
 #else
 #define NULL ((void*)0)
 #endif
+
+#endif
Index: clang/lib/Basic/Module.cpp
===================================================================
--- clang/lib/Basic/Module.cpp
+++ clang/lib/Basic/Module.cpp
@@ -300,7 +300,7 @@
       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")
+  if (!Requested->Parent && 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