1// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=0
2// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -o %t.pcm -verify -DTEST=1
3// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -DTEST=2
4// RUN:     %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %s -fmodule-file=%t.pcm -o %t.pcm -verify -Dfoo=bar -DTEST=3
5
6#if TEST == 0
7// expected-no-diagnostics
8#endif
9
10export module foo;
11#if TEST == 2
12// expected-error@-2 {{redefinition of module 'foo'}}
13// [email protected]:* {{loaded from}}
14#endif
15
16static int m; // ok, internal linkage, so no redefinition error
17int n;
18#if TEST >= 2
19// expected-error@-2 {{redefinition of '}}
20// expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}
21// FIXME: We should drop the "header from" in this diagnostic.
22// [email protected]:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site in header from module 'foo'}}
23#endif
24
25#if TEST == 0
26export {
27  int a;
28  int b;
29  constexpr int *p = &n;
30}
31export int c;
32
33namespace N {
34  export void f() {}
35}
36
37export struct T {} t;
38#elif TEST == 3
39int use_a = a; // expected-error {{declaration of 'a' must be imported from module 'foo' before it is required}}
40// expected-note@-13 {{previous}}
41
42#undef foo
43import foo;
44
45export {} // expected-error {{export declaration cannot be empty}}
46export { ; }
47export { static_assert(true); }
48
49// FIXME: These diagnostics are not very good.
50export import foo; // expected-error {{expected unqualified-id}}
51export { import foo; } // expected-error {{expected unqualified-id}}
52
53int use_b = b;
54int use_n = n; // FIXME: this should not be visible, because it is not exported
55
56extern int n;
57static_assert(&n == p); // FIXME: these are not the same entity
58#endif
59
60
61#if TEST == 1
62struct S {
63  export int n; // expected-error {{expected member name or ';'}}
64  export static int n; // expected-error {{expected member name or ';'}}
65};
66#endif
67
68// FIXME: Exports of declarations without external linkage are disallowed.
69// Exports of declarations with non-external-linkage types are disallowed.
70
71// Cannot export within another export. This isn't precisely covered by the
72// language rules right now, but (per personal correspondence between zygoloid
73// and gdr) is the intent.
74#if TEST == 1
75export {
76  extern "C++" {
77    namespace NestedExport {
78      export { // expected-error {{appears within another export}}
79        int q;
80      }
81    }
82  }
83}
84#endif
85