1 // The test is check we couldn't export a redeclaration which isn't exported previously and 2 // check it is OK to redeclare no matter exported nor not if is the previous declaration is exported. 3 // RUN: %clang_cc1 -std=c++20 %s -verify 4 5 export module X; 6 7 struct S { // expected-note {{previous declaration is here}} 8 int n; 9 }; 10 typedef S S; 11 export typedef S S; // OK, does not redeclare an entity 12 export struct S; // expected-error {{cannot export redeclaration 'S' here since the previous declaration has module linkage}} 13 14 namespace A { 15 struct X; // expected-note {{previous declaration is here}} 16 export struct Y; 17 } // namespace A 18 19 namespace A { 20 export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration has module linkage}} 21 export struct Y; // OK 22 struct Z; // expected-note {{previous declaration is here}} 23 export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration has module linkage}} 24 } // namespace A 25 26 namespace A { 27 struct B; // expected-note {{previous declaration is here}} 28 struct C {}; // expected-note {{previous declaration is here}} 29 } // namespace A 30 31 namespace A { 32 export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration has module linkage}} 33 export struct C; // expected-error {{cannot export redeclaration 'C' here since the previous declaration has module linkage}} 34 } // namespace A 35 36 template <typename T> 37 struct TemplS; // expected-note {{previous declaration is here}} 38 39 export template <typename T> 40 struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration has module linkage}} 41 42 template <typename T> 43 struct TemplS2; // expected-note {{previous declaration is here}} 44 45 export template <typename U> 46 struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration has module linkage}} 47 48 void baz(); // expected-note {{previous declaration is here}} 49 export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration has module linkage}} 50 51 namespace A { 52 export void foo(); 53 void bar(); // expected-note {{previous declaration is here}} 54 export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration has module linkage}} 55 void f1(); // expected-note {{previous declaration is here}} 56 } // namespace A 57 58 // OK 59 // 60 // [module.interface]/p6 61 // A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration 62 void A::foo(); 63 64 // The compiler couldn't export A::f1() here since A::f1() is declared above without exported. 65 // See [module.interface]/p6 for details. 66 export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration has module linkage}} 67 68 template <typename T> 69 void TemplFunc(); // expected-note {{previous declaration is here}} 70 71 export template <typename T> 72 void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration has module linkage}} 73 } 74 75 namespace A { 76 template <typename T> 77 void TemplFunc2(); // expected-note {{previous declaration is here}} 78 export template <typename T> 79 void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration has module linkage}} 80 template <typename T> 81 void TemplFunc3(); // expected-note {{previous declaration is here}} 82 } // namespace A 83 84 export template <typename T> 85 void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration has module linkage}} 86 87 int var; // expected-note {{previous declaration is here}} 88 export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration has module linkage}} 89 90 template <typename T> 91 T TemplVar; // expected-note {{previous declaration is here}} 92 export template <typename T> 93 T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration has module linkage}} 94 95 // Test the compiler wouldn't complain about the redeclaration of friend in exported class. 96 namespace Friend { 97 template <typename T> 98 class bar; 99 class gua; 100 template <typename T> 101 void hello(); 102 void hi(); 103 export class foo; 104 bool operator<(const foo &a, const foo &b); 105 export class foo { 106 template <typename T> 107 friend class bar; 108 friend class gua; 109 template <typename T> 110 friend void hello(); 111 friend void hi(); 112 friend bool operator<(const foo &a, const foo &b); 113 }; 114 } // namespace Friend 115