13a3af2bbSChuanqi Xu // The test is check we couldn't export a redeclaration which isn't exported previously and 23a3af2bbSChuanqi Xu // check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. 33a3af2bbSChuanqi Xu // RUN: %clang_cc1 -std=c++20 %s -verify 43a3af2bbSChuanqi Xu 53a3af2bbSChuanqi Xu export module X; 63a3af2bbSChuanqi Xu 73a3af2bbSChuanqi Xu struct S { // expected-note {{previous declaration is here}} 83a3af2bbSChuanqi Xu int n; 93a3af2bbSChuanqi Xu }; 103a3af2bbSChuanqi Xu typedef S S; 113a3af2bbSChuanqi Xu export typedef S S; // OK, does not redeclare an entity 12*f60dc3caSIain Sandoe export struct S; // expected-error {{cannot export redeclaration 'S' here since the previous declaration has module linkage}} 133a3af2bbSChuanqi Xu 143a3af2bbSChuanqi Xu namespace A { 153a3af2bbSChuanqi Xu struct X; // expected-note {{previous declaration is here}} 163a3af2bbSChuanqi Xu export struct Y; 173a3af2bbSChuanqi Xu } // namespace A 183a3af2bbSChuanqi Xu 193a3af2bbSChuanqi Xu namespace A { 20*f60dc3caSIain Sandoe export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration has module linkage}} 213a3af2bbSChuanqi Xu export struct Y; // OK 223a3af2bbSChuanqi Xu struct Z; // expected-note {{previous declaration is here}} 23*f60dc3caSIain Sandoe export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration has module linkage}} 243a3af2bbSChuanqi Xu } // namespace A 253a3af2bbSChuanqi Xu 263a3af2bbSChuanqi Xu namespace A { 273a3af2bbSChuanqi Xu struct B; // expected-note {{previous declaration is here}} 283a3af2bbSChuanqi Xu struct C {}; // expected-note {{previous declaration is here}} 293a3af2bbSChuanqi Xu } // namespace A 303a3af2bbSChuanqi Xu 313a3af2bbSChuanqi Xu namespace A { 32*f60dc3caSIain Sandoe export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration has module linkage}} 33*f60dc3caSIain Sandoe export struct C; // expected-error {{cannot export redeclaration 'C' here since the previous declaration has module linkage}} 343a3af2bbSChuanqi Xu } // namespace A 353a3af2bbSChuanqi Xu 363a3af2bbSChuanqi Xu template <typename T> 373a3af2bbSChuanqi Xu struct TemplS; // expected-note {{previous declaration is here}} 383a3af2bbSChuanqi Xu 393a3af2bbSChuanqi Xu export template <typename T> 40*f60dc3caSIain Sandoe struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration has module linkage}} 413a3af2bbSChuanqi Xu 423a3af2bbSChuanqi Xu template <typename T> 433a3af2bbSChuanqi Xu struct TemplS2; // expected-note {{previous declaration is here}} 443a3af2bbSChuanqi Xu 453a3af2bbSChuanqi Xu export template <typename U> 46*f60dc3caSIain Sandoe struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration has module linkage}} 473a3af2bbSChuanqi Xu 483a3af2bbSChuanqi Xu void baz(); // expected-note {{previous declaration is here}} 49*f60dc3caSIain Sandoe export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration has module linkage}} 503a3af2bbSChuanqi Xu 513a3af2bbSChuanqi Xu namespace A { 523a3af2bbSChuanqi Xu export void foo(); 533a3af2bbSChuanqi Xu void bar(); // expected-note {{previous declaration is here}} 54*f60dc3caSIain Sandoe export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration has module linkage}} 553a3af2bbSChuanqi Xu void f1(); // expected-note {{previous declaration is here}} 563a3af2bbSChuanqi Xu } // namespace A 573a3af2bbSChuanqi Xu 583a3af2bbSChuanqi Xu // OK 593a3af2bbSChuanqi Xu // 603a3af2bbSChuanqi Xu // [module.interface]/p6 613a3af2bbSChuanqi Xu // A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration 623a3af2bbSChuanqi Xu void A::foo(); 633a3af2bbSChuanqi Xu 643a3af2bbSChuanqi Xu // The compiler couldn't export A::f1() here since A::f1() is declared above without exported. 653a3af2bbSChuanqi Xu // See [module.interface]/p6 for details. 66*f60dc3caSIain Sandoe export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration has module linkage}} 673a3af2bbSChuanqi Xu 683a3af2bbSChuanqi Xu template <typename T> 693a3af2bbSChuanqi Xu void TemplFunc(); // expected-note {{previous declaration is here}} 703a3af2bbSChuanqi Xu 713a3af2bbSChuanqi Xu export template <typename T> TemplFunc()72*f60dc3caSIain Sandoevoid TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration has module linkage}} 733a3af2bbSChuanqi Xu } 743a3af2bbSChuanqi Xu 753a3af2bbSChuanqi Xu namespace A { 763a3af2bbSChuanqi Xu template <typename T> 773a3af2bbSChuanqi Xu void TemplFunc2(); // expected-note {{previous declaration is here}} 783a3af2bbSChuanqi Xu export template <typename T> TemplFunc2()79*f60dc3caSIain Sandoevoid TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration has module linkage}} 803a3af2bbSChuanqi Xu template <typename T> 813a3af2bbSChuanqi Xu void TemplFunc3(); // expected-note {{previous declaration is here}} 823a3af2bbSChuanqi Xu } // namespace A 833a3af2bbSChuanqi Xu 843a3af2bbSChuanqi Xu export template <typename T> TemplFunc3()85*f60dc3caSIain Sandoevoid A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration has module linkage}} 863a3af2bbSChuanqi Xu 873a3af2bbSChuanqi Xu int var; // expected-note {{previous declaration is here}} 88*f60dc3caSIain Sandoe export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration has module linkage}} 893a3af2bbSChuanqi Xu 903a3af2bbSChuanqi Xu template <typename T> 913a3af2bbSChuanqi Xu T TemplVar; // expected-note {{previous declaration is here}} 923a3af2bbSChuanqi Xu export template <typename T> 93*f60dc3caSIain Sandoe T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration has module linkage}} 945c1f7b29SChuanqi Xu 955c1f7b29SChuanqi Xu // Test the compiler wouldn't complain about the redeclaration of friend in exported class. 965c1f7b29SChuanqi Xu namespace Friend { 975c1f7b29SChuanqi Xu template <typename T> 985c1f7b29SChuanqi Xu class bar; 995c1f7b29SChuanqi Xu class gua; 1005c1f7b29SChuanqi Xu template <typename T> 1015c1f7b29SChuanqi Xu void hello(); 1025c1f7b29SChuanqi Xu void hi(); 1035c1f7b29SChuanqi Xu export class foo; 1045c1f7b29SChuanqi Xu bool operator<(const foo &a, const foo &b); 1055c1f7b29SChuanqi Xu export class foo { 1065c1f7b29SChuanqi Xu template <typename T> 1075c1f7b29SChuanqi Xu friend class bar; 1085c1f7b29SChuanqi Xu friend class gua; 1095c1f7b29SChuanqi Xu template <typename T> 1105c1f7b29SChuanqi Xu friend void hello(); 1115c1f7b29SChuanqi Xu friend void hi(); 1125c1f7b29SChuanqi Xu friend bool operator<(const foo &a, const foo &b); 1135c1f7b29SChuanqi Xu }; 1145c1f7b29SChuanqi Xu } // namespace Friend 115