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