Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CXX / module / module.interface / p6.cpp
blob2b7fa78cdbbe6881e33b0191553f5cdfe2bdc647
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
5 export module X;
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}}
14 namespace A {
15 struct X; // expected-note {{previous declaration is here}}
16 export struct Y;
17 } // namespace A
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
26 namespace A {
27 struct B; // expected-note {{previous declaration is here}}
28 struct C {}; // expected-note {{previous declaration is here}}
29 } // namespace A
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
36 template <typename T>
37 struct TemplS; // expected-note {{previous declaration is here}}
39 export template <typename T>
40 struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration has module linkage}}
42 template <typename T>
43 struct TemplS2; // expected-note {{previous declaration is here}}
45 export template <typename U>
46 struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration has module linkage}}
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}}
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
58 // OK
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();
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}}
68 template <typename T>
69 void TemplFunc(); // expected-note {{previous declaration is here}}
71 export template <typename T>
72 void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration has module linkage}}
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
84 export template <typename T>
85 void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration has module linkage}}
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}}
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}}
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);
114 } // namespace Friend