Richard Smith | dd8b533 | 2017-09-04 05:37:53 +0000 | [diff] [blame] | 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 |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 5 | |
| 6 | #if TEST == 0 |
| 7 | // expected-no-diagnostics |
| 8 | #endif |
| 9 | |
Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 10 | export module foo; |
Richard Smith | 145e15a | 2017-04-24 23:12:30 +0000 | [diff] [blame] | 11 | #if TEST == 2 |
| 12 | // expected-error@-2 {{redefinition of module 'foo'}} |
| 13 | // expected-note@modules-ts.cppm:* {{loaded from}} |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 14 | #endif |
| 15 | |
Richard Smith | e03a654 | 2017-07-05 01:42:07 +0000 | [diff] [blame] | 16 | static int m; |
Richard Smith | becb92d | 2017-10-10 22:33:17 +0000 | [diff] [blame] | 17 | #if TEST == 2 |
Richard Smith | e03a654 | 2017-07-05 01:42:07 +0000 | [diff] [blame] | 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 |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 23 | int n; |
Richard Smith | dd8b533 | 2017-09-04 05:37:53 +0000 | [diff] [blame] | 24 | #if TEST == 2 |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 25 | // expected-error@-2 {{redefinition of '}} |
Bruno Cardoso Lopes | 0ad3182 | 2017-05-11 06:20:07 +0000 | [diff] [blame] | 26 | // expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}} |
Richard Smith | 54f0440 | 2017-05-18 02:29:20 +0000 | [diff] [blame] | 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'}} |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 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}} |
Richard Smith | e181de7 | 2019-04-22 22:50:11 +0000 | [diff] [blame^] | 52 | export { // expected-note {{begins here}} |
| 53 | ; // expected-warning {{ISO C++20 does not permit an empty declaration to appear in an export block}} |
| 54 | } |
| 55 | export { // expected-note {{begins here}} |
| 56 | static_assert(true); // expected-warning {{ISO C++20 does not permit a static_assert declaration to appear in an export block}} |
| 57 | } |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 58 | |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 59 | int use_b = b; |
| 60 | int use_n = n; // FIXME: this should not be visible, because it is not exported |
| 61 | |
| 62 | extern int n; |
Richard Smith | dd8b533 | 2017-09-04 05:37:53 +0000 | [diff] [blame] | 63 | static_assert(&n != p); |
Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 64 | #endif |
| 65 | |
| 66 | |
| 67 | #if TEST == 1 |
| 68 | struct S { |
| 69 | export int n; // expected-error {{expected member name or ';'}} |
| 70 | export static int n; // expected-error {{expected member name or ';'}} |
| 71 | }; |
| 72 | #endif |
| 73 | |
| 74 | // FIXME: Exports of declarations without external linkage are disallowed. |
| 75 | // Exports of declarations with non-external-linkage types are disallowed. |
Richard Smith | 3b66056 | 2016-09-26 21:27:23 +0000 | [diff] [blame] | 76 | |
| 77 | // Cannot export within another export. This isn't precisely covered by the |
| 78 | // language rules right now, but (per personal correspondence between zygoloid |
| 79 | // and gdr) is the intent. |
| 80 | #if TEST == 1 |
Richard Smith | e181de7 | 2019-04-22 22:50:11 +0000 | [diff] [blame^] | 81 | export { // expected-note {{export block begins here}} |
Richard Smith | 3b66056 | 2016-09-26 21:27:23 +0000 | [diff] [blame] | 82 | extern "C++" { |
| 83 | namespace NestedExport { |
| 84 | export { // expected-error {{appears within another export}} |
| 85 | int q; |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | #endif |