xref: /llvm-project/clang/test/Modules/stddef.cpp (revision 92a9d4831d5e40c286247c30fcd794563adbef6e)
1 // RUN: rm -rf %t
2 // RUN: split-file %s %t
3 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/no-lsv -I%t %t/stddef.cpp -verify
4 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-local-submodule-visibility -fmodules-cache-path=%t/lsv -I%t %t/stddef.cpp -verify
5 
6 //--- stddef.cpp
7 #include <b.h>
8 
9 void *pointer = NULL;
10 size_t size = 0;
11 
12 // When building with modules, a pcm is never re-imported, so re-including
13 // stddef.h will not re-import _Builtin_stddef.null to restore the definition of
14 // NULL, even though stddef.h will unconditionally include __stddef_null.h when
15 // building with modules.
16 #undef NULL
17 #include <stddef.h>
18 
19 void *anotherPointer = NULL; // expected-error{{use of undeclared identifier 'NULL'}}
20 
21 // stddef.h needs to be a `textual` header to support clients doing things like
22 // this.
23 //
24 // #define __need_NULL
25 // #include <stddef.h>
26 //
27 // As a textual header designed to be included multiple times, it can't directly
28 // declare anything, or those declarations would go into every module that
29 // included it. e.g. if stddef.h contained all of its declarations, and modules
30 // A and B included stddef.h, they would both have the declaration for size_t.
31 // That breaks Swift, which uses the module name as part of the type name, i.e.
32 // A.size_t and B.size_t are treated as completely different types in Swift and
33 // cannot be interchanged. To fix that, stddef.h (and stdarg.h) are split out
34 // into a separate file per __need macro that can be normal headers in explicit
35 // submodules. That runs into yet another wrinkle though. When modules build,
36 // declarations from previous submodules leak into subsequent ones when not
37 // using local submodule visibility. Consider if stddef.h did the normal thing.
38 //
39 // #ifndef __STDDEF_H
40 // #define __STDDEF_H
41 // // include all of the sub-headers
42 // #endif
43 //
44 // When SM builds without local submodule visibility, it will precompile a.h
45 // first. When it gets to b.h, the __STDDEF_H declaration from precompiling a.h
46 // will leak, and so when b.h includes stddef.h, it won't include any of its
47 // sub-headers, and SM.B will thus not import _Builtin_stddef or make any of its
48 // submodules visible. Precompiling b.h will be fine since it sees all of the
49 // declarations from a.h including stddef.h, but clients that only include b.h
50 // will not see any of the stddef.h types. stddef.h thus has to make sure to
51 // always include the necessary sub-headers, even if they've been included
52 // already. They all have their own header guards to allow this.
53 // __stddef_null.h is extra special, so this test makes sure to cover NULL plus
54 // one of the normal stddef.h types.
55 
56 //--- module.modulemap
57 module SM {
58   module A {
59     header "a.h"
60     export *
61   }
62 
63   module B {
64     header "b.h"
65     export *
66   }
67 }
68 
69 //--- a.h
70 #include <stddef.h>
71 
72 //--- b.h
73 #include <stddef.h>
74