// The test is check we couldn't export a redeclaration which isn't exported previously and // check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. // RUN: %clang_cc1 -std=c++20 %s -verify export module X; struct S { // expected-note {{previous declaration is here}} int n; }; typedef S S; export typedef S S; // OK, does not redeclare an entity export struct S; // expected-error {{cannot export redeclaration 'S' here since the previous declaration has module linkage}} namespace A { struct X; // expected-note {{previous declaration is here}} export struct Y; } // namespace A namespace A { export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration has module linkage}} export struct Y; // OK struct Z; // expected-note {{previous declaration is here}} export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration has module linkage}} } // namespace A namespace A { struct B; // expected-note {{previous declaration is here}} struct C {}; // expected-note {{previous declaration is here}} } // namespace A namespace A { export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration has module linkage}} export struct C; // expected-error {{cannot export redeclaration 'C' here since the previous declaration has module linkage}} } // namespace A template struct TemplS; // expected-note {{previous declaration is here}} export template struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration has module linkage}} template struct TemplS2; // expected-note {{previous declaration is here}} export template struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration has module linkage}} void baz(); // expected-note {{previous declaration is here}} export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration has module linkage}} namespace A { export void foo(); void bar(); // expected-note {{previous declaration is here}} export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration has module linkage}} void f1(); // expected-note {{previous declaration is here}} } // namespace A // OK // // [module.interface]/p6 // A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration void A::foo(); // The compiler couldn't export A::f1() here since A::f1() is declared above without exported. // See [module.interface]/p6 for details. export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration has module linkage}} template void TemplFunc(); // expected-note {{previous declaration is here}} export template void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration has module linkage}} } namespace A { template void TemplFunc2(); // expected-note {{previous declaration is here}} export template void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration has module linkage}} template void TemplFunc3(); // expected-note {{previous declaration is here}} } // namespace A export template void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration has module linkage}} int var; // expected-note {{previous declaration is here}} export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration has module linkage}} template T TemplVar; // expected-note {{previous declaration is here}} export template T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration has module linkage}} // Test the compiler wouldn't complain about the redeclaration of friend in exported class. namespace Friend { template class bar; class gua; template void hello(); void hi(); export class foo; bool operator<(const foo &a, const foo &b); export class foo { template friend class bar; friend class gua; template friend void hello(); friend void hi(); friend bool operator<(const foo &a, const foo &b); }; } // namespace Friend