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 10export 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 16static 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 23int 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 32export { 33 int a; 34 int b; 35 constexpr int *p = &n; 36} 37export int c; 38 39namespace N { 40 export void f() {} 41} 42 43export struct T {} t; 44#elif TEST == 3 45int use_a = a; // expected-error {{declaration of 'a' must be imported from module 'foo' before it is required}} 46// expected-note@-13 {{declaration here is not visible}} 47 48#undef foo 49import foo; 50 51export {} // expected-error {{export declaration cannot be empty}} 52export { // expected-note {{begins here}} 53 ; // expected-warning {{ISO C++20 does not permit an empty declaration to appear in an export block}} 54} 55export { // 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} 58 59int use_b = b; 60int use_n = n; // FIXME: this should not be visible, because it is not exported 61 62extern int n; 63static_assert(&n != p); 64#endif 65 66 67#if TEST == 1 68struct 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. 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 81export { // expected-note {{export block begins here}} 82 extern "C++" { 83 namespace NestedExport { 84 export { // expected-error {{appears within another export}} 85 int q; 86 } 87 } 88 } 89} 90#endif 91