File: func.spec.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (247 lines) | stat: -rw-r--r-- 8,913 bytes parent folder | download | duplicates (18)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s

// C++20 [temp.spec] 13.9/6:
//   The usual access checking rules do not apply to names in a declaration
//   of an explicit instantiation or explicit specialization, with the
//   exception of names appearing in a function body, default argument,
//   base-clause, member-specification, enumerator-list, or static data member
//   or variable template initializer.
//   [Note : In particular, the template arguments and names used in the
//   function declarator(including parameter types, return types and exception
//   specifications) may be private types or objects that would normally not be
//   accessible.  end note]

class A {
  // expected-note@+1 17{{implicitly declared private here}}
  template <typename T> class B {};
  // expected-note@+1 3{{implicitly declared private here}}
  static constexpr int num1 = 42;

protected:
  // expected-note@+1 13{{declared protected here}}
  class C {};
  // expected-note@+1 2{{declared protected here}}
  static constexpr int num2 = 43;
  static int num4;

public:
  template <typename T> class D {};
  static constexpr int num3 = 44;
};
int A::num4 = 44;

class E : public A {

  // Declarations

  // expected-error@+1 {{is a private member of}}
  template <typename T = A::B<int>> void func1();
  template <typename T = A::C> void func2();
  template <typename T = class A::D<int>> void func3();
  // expected-error@+1 {{is a private member of}}
  template <typename T> A::B<int> func4();
  // expected-error@+1 {{is a private member of}}
  template <typename T> A::B<T> func5();
  template <typename T> class A::C func6();
  template <typename T> class A::D<int> func7();
  // expected-error@+1 2{{is a private member of}}
  template <typename T> void func8(class A::B<T>, int x = A::num1);
  template <typename T> void func9(A::C, A::D<T>, int = A::num3);

  // Specializations inside class declaration
  template <> void func1<A::B<char>>() {}
  template <> void func2<class A::D<char>>() {
  } template <> void func3<class A::C>() {
  }
  template <> class A::B<int> func4<A::B<char>>() { return {}; } template <> A::B<A::D<int>> func5<A::D<int>>() {
    return {};
  }
  template <> class A::C func6<A::C>() { return {}; } template <> A::D<int> func7<char>() {
    return {};
  }
  template <> void func8<char>(class A::B<char>, int) {}
  template <> void func9<A::B<char>>(A::C, A::D<A::B<char>>, int) {}

  // FIXME: Instantiations inside class declaration.
  // don't work correctly.
};

// Definitions

template <typename T> void E::func1() {}
template <typename T> void E::func2() {}
template <typename T> void E::func3() {}
// expected-error@+1 {{is a private member of}}
template <typename T> A::B<int> E::func4() { return {}; }
// expected-error@+1 {{is a private member of}}
template <typename T> A::B<T> E::func5() { return {}; }
template <typename T> A::C E::func6() { return {}; }
template <typename T> A::D<int> E::func7() { return {}; }
// expected-error@+1 {{is a private member of}}
template <typename T> void E::func8(A::B<T>, int) {}
template <typename T> void E::func9(A::C, A::D<T>, int) {}

// Specializations

template <> void E::func1<A::B<int>>() {}
template <> void E::func2<class A::C>() {}
template <> void E::func3<class A::D<int>>() {
} template <> class A::B<int> E::func4<A::B<int>>() {
  return {};
} template <> A::B<A::C> E::func5<A::C>() {
  return {};
}
template <> class A::C E::func6<A::D<int>>() { return {}; } template <> A::D<int> E::func7<int>() {
  return {};
}
template <> void E::func8<int>(class A::B<int>, int) {}
template <> void E::func9<A::C>(A::C, A::D<A::C>, int) {}

// Instantiations

template <> void E::func1<A::B<int>>();
template <> void E::func2<class A::C>();
template <> void E::func3<class A::D<int>>();
template <> class A::B<int> E::func4<A::B<int>>();
template <> A::B<A::C> E::func5<A::C>();
template <> class A::C E::func6<A::D<int>>();
template <> A::D<int> E::func7<int>();
template <> void E::func8<int>(class A::B<int>, int);
template <> void E::func9<A::C>(A::C, A::D<A::C>, int);

//----------------------------------------------------------//

// forward declarations

// expected-error@+1 {{is a protected member of}}
template <typename T> class A::C func1();
// expected-error@+1 {{is a private member of}}
template <typename T> A::B<T> func2();
template <typename T> A::D<T> func3();
// expected-error@+1 {{is a private member of}}
template <typename T> class A::B<int> func4();
template <typename T> void func5();
// expected-error@+1 {{is a private member of}}
template <int x = A::num1> void func6();
// expected-error@+1 {{is a protected member of}}
template <int x = A::num2> void func7();
// expected-error@+1 {{is a protected member of}}
template <typename T> void func8(int x = sizeof(A::C));
// expected-error@+1 {{is a private member of}}
template <typename T> void func9(int x = A::num1);
// expected-error@+2 {{is a private member of}}
// expected-error@+1 {{is a protected member of}}
template <typename T> void func10(class A::B<T>, int x = A::num2);
// expected-error@+1 {{is a protected member of}}
template <typename T> void func11(class A::C, A::D<T>, int = A::num3);
template <typename T> void func12();
template <int x> void func13();
template <typename T, int x> void func14();
template <template <typename> typename T> void func15();
// expected-error@+1 {{is a protected member of}}
template <typename T = A::C> void func16();
// expected-error@+1 {{is a private member of}}
template <typename T = A::B<int>> void func17();
// expected-error@+1 {{is a protected member of}}
template <typename T> auto func18() -> A::C;
template <typename T> T func19();

//----------------------------------------------------------//

// definitions

// expected-error@+1 2{{is a protected member of}}
template <typename T> A::C func1() { A::C x; }
// expected-error@+2 {{is a private member of}}
// expected-error@+1 {{is a protected member of}}
template <typename T> A::B<T> func2() { A::D<A::C> x; }
template <typename T> A::D<T> func3() { A::D<int> x; }
// expected-error@+2 2{{is a private member of}}
// expected-error@+1 {{is a protected member of}}
template <typename T> class A::B<int> func4() { A::B<A::C> x; }

template <typename T>
void func5() {
  // expected-error@+2 {{is a private member of}}
  // expected-error@+1 {{is a protected member of}}
  A::B<A::D<A::C>> x;
  // expected-error@+1 {{is a private member of}}
  A::B<int> x2;
}
template <typename T> void func8(int x) {}
template <typename T> void func9(int x) {}
// expected-error@+1 {{is a private member of}}
template <typename T> void func10(A::B<T>, int x) {}
// expected-error@+1 {{is a protected member of}}
template <typename T> void func11(A::C, A::D<T>, int) {}
template <typename T> void func12() {}
template <int x> void func13() {}
template <typename T, int x> void func14() {}
template <template <typename> typename T> void func15() {}
template <typename T> void func16() {}
template <typename T> void func17() {}
// expected-error@+1 {{is a protected member of}}
template <typename T> auto func18() -> A::C {
  // expected-error@+1 {{is a protected member of}}
  return A::C{};
}
template <typename T> T func19() {
  return T{};
}

//----------------------------------------------------------//

// explicit specializations

template <> A::C func1<A::C>();
template <> A::B<A::C> func2<A::C>();
template <> A::D<A::C> func3<A::C>();
template <> class A::B<int> func4<A::C>();
template <> void func5<A::C>();
template <> void func5<A::B<int>>();
template <> void func5<A::D<A::C>>();
template <> void func5<int>();
template <> void func8<A::C>(int x);
template <> void func9<decltype(A::num1)>(int);
template <> void func10<A::D<int>>(A::B<A::D<int>>, int);
template <> void func11<A::C>(A::C, A::D<A::C>, int);
template <> void func12<class A::B<char>>() {
} template <> void func13<A::num1>() {
}
template <> void func14<A::B<int>, A::num2>() {}
template <> void func15<A::D>() {}
template <> void func16<class A::B<char>>() {
} template <> void func17<A::B<class A::C>>() {
}
template <> auto func18<int>() -> class A::C;
template <> A::B<int> func19<class A::B<int>>();

//----------------------------------------------------------//

// explicit instantiations

template void func10<A::C>(A::B<A::C>, decltype(A::num1));
template void func11<A::B<int>>(A::C, A::D<A::B<int>>, decltype(A::num2));
template void func12<A::C>();
template void func13<A::num2>();
template void func13<A::num3>();
template void func14<A::C, A::num1>();
template void func15<A::B>();
template void func17();
template auto func18<char>() -> A::C;
template class A::C func19<A::C>();

//----------------------------------------------------------//

// Other cases

template <int *x> class StealClass {
  friend int stealFunc() { return *x; }
};

template class StealClass<&A::num4>;
int stealFunc();

int stealFunc2() {
  return stealFunc();
}