aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CXX/module/module.interface/p6.cpp
blob: 2b7fa78cdbbe6881e33b0191553f5cdfe2bdc647 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// The test is check we couldn't export a redeclaration which isn't exported previously and
// check it is OK to redeclare no matter exported nor not if is the previous declaration is exported.
// RUN: %clang_cc1 -std=c++20 %s -verify

export module X;

struct S { // expected-note {{previous declaration is here}}
  int n;
};
typedef S S;
export typedef S S; // OK, does not redeclare an entity
export struct S;    // expected-error {{cannot export redeclaration 'S' here since the previous declaration has module linkage}}

namespace A {
struct X; // expected-note {{previous declaration is here}}
export struct Y;
} // namespace A

namespace A {
export struct X; // expected-error {{cannot export redeclaration 'X' here since the previous declaration has module linkage}}
export struct Y; // OK
struct Z;        // expected-note {{previous declaration is here}}
export struct Z; // expected-error {{cannot export redeclaration 'Z' here since the previous declaration has module linkage}}
} // namespace A

namespace A {
struct B;    // expected-note {{previous declaration is here}}
struct C {}; // expected-note {{previous declaration is here}}
} // namespace A

namespace A {
export struct B {}; // expected-error {{cannot export redeclaration 'B' here since the previous declaration has module linkage}}
export struct C;    // expected-error {{cannot export redeclaration 'C' here since the previous declaration has module linkage}}
} // namespace A

template <typename T>
struct TemplS; // expected-note {{previous declaration is here}}

export template <typename T>
struct TemplS {}; // expected-error {{cannot export redeclaration 'TemplS' here since the previous declaration has module linkage}}

template <typename T>
struct TemplS2; // expected-note {{previous declaration is here}}

export template <typename U>
struct TemplS2 {}; // expected-error {{cannot export redeclaration 'TemplS2' here since the previous declaration has module linkage}}

void baz();        // expected-note {{previous declaration is here}}
export void baz(); // expected-error {{cannot export redeclaration 'baz' here since the previous declaration has module linkage}}

namespace A {
export void foo();
void bar();        // expected-note {{previous declaration is here}}
export void bar(); // expected-error {{cannot export redeclaration 'bar' here since the previous declaration has module linkage}}
void f1();         // expected-note {{previous declaration is here}}
} // namespace A

// OK
//
// [module.interface]/p6
// A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration
void A::foo();

// The compiler couldn't export A::f1() here since A::f1() is declared above without exported.
// See [module.interface]/p6 for details.
export void A::f1(); // expected-error {{cannot export redeclaration 'f1' here since the previous declaration has module linkage}}

template <typename T>
void TemplFunc(); // expected-note {{previous declaration is here}}

export template <typename T>
void TemplFunc() { // expected-error {{cannot export redeclaration 'TemplFunc' here since the previous declaration has module linkage}}
}

namespace A {
template <typename T>
void TemplFunc2(); // expected-note {{previous declaration is here}}
export template <typename T>
void TemplFunc2() {} // expected-error {{cannot export redeclaration 'TemplFunc2' here since the previous declaration has module linkage}}
template <typename T>
void TemplFunc3(); // expected-note {{previous declaration is here}}
} // namespace A

export template <typename T>
void A::TemplFunc3() {} // expected-error {{cannot export redeclaration 'TemplFunc3' here since the previous declaration has module linkage}}

int var;        // expected-note {{previous declaration is here}}
export int var; // expected-error {{cannot export redeclaration 'var' here since the previous declaration has module linkage}}

template <typename T>
T TemplVar; // expected-note {{previous declaration is here}}
export template <typename T>
T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration has module linkage}}

// Test the compiler wouldn't complain about the redeclaration of friend in exported class.
namespace Friend {
template <typename T>
class bar;
class gua;
template <typename T>
void hello();
void hi();
export class foo;
bool operator<(const foo &a, const foo &b);
export class foo {
  template <typename T>
  friend class bar;
  friend class gua;
  template <typename T>
  friend void hello();
  friend void hi();
  friend bool operator<(const foo &a, const foo &b);
};
} // namespace Friend