xref: /llvm-project/clang/test/CXX/module/module.interface/p6.cpp (revision f60dc3caa67374c0e2941ee3866b5eaef0c6ffe6)
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 Sandoe void 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 Sandoe void 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 Sandoe void 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