1e867e983SRichard Smith // RUN: rm -rf %t
2e867e983SRichard Smith // RUN: mkdir -p %t
3e867e983SRichard Smith // RUN: echo '#ifndef FOO_H' > %t/foo.h
4e867e983SRichard Smith // RUN: echo '#define FOO_H' >> %t/foo.h
5e867e983SRichard Smith // RUN: echo 'extern int in_header;' >> %t/foo.h
6e867e983SRichard Smith // RUN: echo '#endif' >> %t/foo.h
7e867e983SRichard Smith // RUN: %clang_cc1 -std=c++2a -I%t -emit-module-interface -DINTERFACE %s -o %t.pcm
8e867e983SRichard Smith // RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=%t.pcm -DIMPLEMENTATION %s -verify -fno-modules-error-recovery
9e867e983SRichard Smith // RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=%t.pcm %s -verify -fno-modules-error-recovery
10e867e983SRichard Smith 
11e867e983SRichard Smith #ifdef INTERFACE
12e867e983SRichard Smith module;
13e867e983SRichard Smith #include "foo.h"
140a088eadSRichard Smith // FIXME: The following need to be moved to a header file. The global module
150a088eadSRichard Smith // fragment is only permitted to contain preprocessor directives.
16e867e983SRichard Smith int global_module_fragment;
17e867e983SRichard Smith export module A;
18e867e983SRichard Smith export int exported;
19e867e983SRichard Smith int not_exported;
20e867e983SRichard Smith static int internal;
21e867e983SRichard Smith 
22e867e983SRichard Smith module :private;
23e867e983SRichard Smith int not_exported_private;
24e867e983SRichard Smith static int internal_private;
25e867e983SRichard Smith #else
26e867e983SRichard Smith 
27e867e983SRichard Smith #ifdef IMPLEMENTATION
28e867e983SRichard Smith module;
29e867e983SRichard Smith #endif
30e867e983SRichard Smith 
31e867e983SRichard Smith void test_early() {
32e867e983SRichard Smith   in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
330a088eadSRichard Smith   // expected-note@* {{not visible}}
34e867e983SRichard Smith 
35e867e983SRichard Smith   global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
360a088eadSRichard Smith                               // [email protected]:16 {{not visible}}
37e867e983SRichard Smith 
38e867e983SRichard Smith   exported = 1; // expected-error {{must be imported from module 'A'}}
39*9c04851cSChuanqi Xu                 // [email protected]:18 {{declaration here is not visible}}
40e867e983SRichard Smith 
41*9c04851cSChuanqi Xu   not_exported = 1; // expected-error {{declaration of 'not_exported' must be imported from module 'A' before it is required}}
42*9c04851cSChuanqi Xu                     // [email protected]:19 {{declaration here is not visible}}
43e867e983SRichard Smith 
44*9c04851cSChuanqi Xu   // FIXME: We need better diagnostic message for static variable.
45*9c04851cSChuanqi Xu   internal = 1; // expected-error {{declaration of 'internal' must be imported from module 'A' before it is required}}
46*9c04851cSChuanqi Xu                 // [email protected]:20 {{declaration here is not visible}}
47e867e983SRichard Smith 
48e867e983SRichard Smith   not_exported_private = 1; // expected-error {{undeclared identifier}}
49e867e983SRichard Smith 
50e867e983SRichard Smith   internal_private = 1; // expected-error {{undeclared identifier}}
51e867e983SRichard Smith }
52e867e983SRichard Smith 
53e867e983SRichard Smith #ifdef IMPLEMENTATION
54e867e983SRichard Smith module A;
55e867e983SRichard Smith #else
56e867e983SRichard Smith import A;
57e867e983SRichard Smith #endif
58e867e983SRichard Smith 
59e867e983SRichard Smith void test_late() {
60e867e983SRichard Smith   in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
610a088eadSRichard Smith   // expected-note@* {{not visible}}
62e867e983SRichard Smith 
63e867e983SRichard Smith   global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
640a088eadSRichard Smith   // [email protected]:16 {{not visible}}
65e867e983SRichard Smith 
66e867e983SRichard Smith   exported = 1;
67e867e983SRichard Smith 
68e867e983SRichard Smith   not_exported = 1;
69e867e983SRichard Smith #ifndef IMPLEMENTATION
70*9c04851cSChuanqi Xu   // expected-error@-2 {{declaration of 'not_exported' must be imported from module 'A' before it is required}}
71*9c04851cSChuanqi Xu   // [email protected]:19 {{declaration here is not visible}}
72e867e983SRichard Smith #endif
73e867e983SRichard Smith 
74e867e983SRichard Smith   internal = 1;
75e867e983SRichard Smith #ifndef IMPLEMENTATION
76*9c04851cSChuanqi Xu   // expected-error@-2 {{declaration of 'internal' must be imported from module 'A' before it is required}}
77*9c04851cSChuanqi Xu   // [email protected]:20 {{declaration here is not visible}}
78e867e983SRichard Smith #endif
79e867e983SRichard Smith 
80e867e983SRichard Smith   not_exported_private = 1;
81e867e983SRichard Smith #ifndef IMPLEMENTATION
82e867e983SRichard Smith   // FIXME: should not be visible here
83e867e983SRichard Smith   // expected-error@-3 {{undeclared identifier}}
84e867e983SRichard Smith #endif
85e867e983SRichard Smith 
86e867e983SRichard Smith   internal_private = 1;
87e867e983SRichard Smith #ifndef IMPLEMENTATION
88e867e983SRichard Smith   // FIXME: should not be visible here
89e867e983SRichard Smith   // expected-error@-3 {{undeclared identifier}}
90e867e983SRichard Smith #endif
91e867e983SRichard Smith }
92e867e983SRichard Smith 
93e867e983SRichard Smith #endif
94