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