xref: /llvm-project/clang/test/CXX/temp/temp.spec/part.spec.cpp (revision 1156bbc5b1837e688b0e5d6952f1a900aca29062)
1638dcea0SAlex Orlov // RUN: %clang_cc1 -fsyntax-only -verify %s
2638dcea0SAlex Orlov 
3638dcea0SAlex Orlov // C++20 [temp.class.spec] 13.7.5/10
4638dcea0SAlex Orlov //   The usual access checking rules do not apply to non-dependent names
5638dcea0SAlex Orlov //   used to specify template arguments of the simple-template-id of the
6638dcea0SAlex Orlov //   partial specialization.
7638dcea0SAlex Orlov //
8638dcea0SAlex Orlov // C++20 [temp.spec] 13.9/6:
9638dcea0SAlex Orlov //   The usual access checking rules do not apply to names in a declaration
10638dcea0SAlex Orlov //   of an explicit instantiation or explicit specialization...
11638dcea0SAlex Orlov 
12638dcea0SAlex Orlov // TODO: add test cases for `enum`
13638dcea0SAlex Orlov 
14638dcea0SAlex Orlov // class for tests
15638dcea0SAlex Orlov class TestClass {
16638dcea0SAlex Orlov public:
17638dcea0SAlex Orlov   class PublicClass {};
18638dcea0SAlex Orlov   template <class T> class TemplatePublicClass {};
19638dcea0SAlex Orlov 
20638dcea0SAlex Orlov   using AliasPublicClass = unsigned char;
21638dcea0SAlex Orlov 
22638dcea0SAlex Orlov   void publicFunc();
23638dcea0SAlex Orlov   void publicFuncOverloaded();
24638dcea0SAlex Orlov   void publicFuncOverloaded(int);
25638dcea0SAlex Orlov 
26638dcea0SAlex Orlov   static void publicStaticFunc();
27638dcea0SAlex Orlov   static void publicStaticFuncOverloaded();
28638dcea0SAlex Orlov   static void publicStaticFuncOverloaded(int);
29638dcea0SAlex Orlov 
30638dcea0SAlex Orlov   static constexpr int publicStaticInt = 42;
31638dcea0SAlex Orlov 
32638dcea0SAlex Orlov protected:
33638dcea0SAlex Orlov   // expected-note@+1 8{{declared protected here}}
34638dcea0SAlex Orlov   class ProtectedClass {};
35638dcea0SAlex Orlov   template <class T> class TemplateProtectedClass {};
36638dcea0SAlex Orlov 
37638dcea0SAlex Orlov   // expected-note@+1 2{{declared protected here}}
38638dcea0SAlex Orlov   using AliasProtectedClass = const char;
39638dcea0SAlex Orlov 
40638dcea0SAlex Orlov   // expected-note@+1 3{{declared protected here}}
41638dcea0SAlex Orlov   void protectedFunc();
42638dcea0SAlex Orlov   void protectedFuncOverloaded();
43638dcea0SAlex Orlov   void protectedFuncOverloaded(int);
44638dcea0SAlex Orlov 
45638dcea0SAlex Orlov   // expected-note@+1 2{{declared protected here}}
46638dcea0SAlex Orlov   static void protectedStaticFunc();
47638dcea0SAlex Orlov   // expected-note@+1 2{{declared protected here}}
48638dcea0SAlex Orlov   static void protectedStaticFuncOverloaded();
49638dcea0SAlex Orlov   static void protectedStaticFuncOverloaded(int);
50638dcea0SAlex Orlov 
51638dcea0SAlex Orlov   // expected-note@+1 2{{declared protected here}}
52638dcea0SAlex Orlov   static constexpr int protectedStaticInt = 43;
53638dcea0SAlex Orlov 
54638dcea0SAlex Orlov private:
55638dcea0SAlex Orlov   // expected-note@+1 10{{declared private here}}
56638dcea0SAlex Orlov   class PrivateClass {};
57638dcea0SAlex Orlov   // expected-note@+1 {{declared private here}}
58638dcea0SAlex Orlov   template <class T> class TemplatePrivateClass {};
59638dcea0SAlex Orlov 
60638dcea0SAlex Orlov   using AliasPrivateClass = char *;
61638dcea0SAlex Orlov 
62638dcea0SAlex Orlov   void privateFunc();
63638dcea0SAlex Orlov   void privateFuncOverloaded();
64638dcea0SAlex Orlov   void privateFuncOverloaded(int);
65638dcea0SAlex Orlov 
66638dcea0SAlex Orlov   static void privateStaticFunc();
67638dcea0SAlex Orlov   static void privateStaticFuncOverloaded();
68638dcea0SAlex Orlov   static void privateStaticFuncOverloaded(int);
69638dcea0SAlex Orlov 
70638dcea0SAlex Orlov   static constexpr int privateStaticInt = 44;
71638dcea0SAlex Orlov };
72638dcea0SAlex Orlov 
globalFunction()73638dcea0SAlex Orlov void globalFunction() {}
74638dcea0SAlex Orlov 
75638dcea0SAlex Orlov //----------------------------------------------------------//
76638dcea0SAlex Orlov 
77638dcea0SAlex Orlov // template declarations for explicit instantiations
78638dcea0SAlex Orlov template <typename T> class IT1 {};
79638dcea0SAlex Orlov template <typename T1, typename T2> class IT2 {};
80638dcea0SAlex Orlov template <int X> class IT3 {};
81638dcea0SAlex Orlov template <void (TestClass::*)()> class IT4 {};
82638dcea0SAlex Orlov template <void (*)()> class IT5 {};
83638dcea0SAlex Orlov template <typename T> class IT6 {
84638dcea0SAlex Orlov   template <typename NT> class NIT1 {};
85638dcea0SAlex Orlov };
86638dcea0SAlex Orlov template <typename T1, typename T2> class IT7 {};
87638dcea0SAlex Orlov template <void (TestClass::*)(), int X> class IT8 {};
88638dcea0SAlex Orlov template <typename T, void (*)()> class IT9 {};
89638dcea0SAlex Orlov 
90638dcea0SAlex Orlov // explicit instantiations
91638dcea0SAlex Orlov 
92638dcea0SAlex Orlov // public
93638dcea0SAlex Orlov template class IT1<TestClass::PublicClass>;
94638dcea0SAlex Orlov template struct IT1<TestClass::TemplatePublicClass<int>>;
95638dcea0SAlex Orlov template class IT1<TestClass::AliasPublicClass>;
96638dcea0SAlex Orlov template struct IT2<TestClass::PublicClass, TestClass::PublicClass>;
97638dcea0SAlex Orlov template class IT3<TestClass::publicStaticInt>;
98638dcea0SAlex Orlov template struct IT4<&TestClass::publicFunc>;
99638dcea0SAlex Orlov template class IT4<&TestClass::publicFuncOverloaded>;
100638dcea0SAlex Orlov template class IT5<&TestClass::publicStaticFunc>;
101638dcea0SAlex Orlov template class IT5<&TestClass::publicStaticFuncOverloaded>;
102638dcea0SAlex Orlov template class IT5<&globalFunction>;
103638dcea0SAlex Orlov template class IT6<TestClass::PublicClass>::template NIT1<TestClass::PublicClass>;
104638dcea0SAlex Orlov template class IT7<TestClass::AliasPublicClass, TestClass::PublicClass>;
105638dcea0SAlex Orlov template struct IT7<TestClass::PublicClass, TestClass::TemplatePublicClass<TestClass::PublicClass>>;
106638dcea0SAlex Orlov template class IT8<&TestClass::publicFunc, TestClass::publicStaticInt>;
107638dcea0SAlex Orlov template class IT8<&TestClass::publicFuncOverloaded, TestClass::publicStaticInt>;
108638dcea0SAlex Orlov template class IT9<TestClass::PublicClass, &TestClass::publicStaticFunc>;
109638dcea0SAlex Orlov template class IT9<TestClass::PublicClass, &TestClass::publicStaticFuncOverloaded>;
110638dcea0SAlex Orlov template class IT9<TestClass::PublicClass, &globalFunction>;
111638dcea0SAlex Orlov 
112638dcea0SAlex Orlov // protected
113638dcea0SAlex Orlov template class IT1<TestClass::ProtectedClass>;
114638dcea0SAlex Orlov template struct IT1<TestClass::TemplateProtectedClass<int>>;
115638dcea0SAlex Orlov template class IT1<TestClass::AliasProtectedClass>;
116638dcea0SAlex Orlov template struct IT2<TestClass::ProtectedClass, TestClass::ProtectedClass>;
117638dcea0SAlex Orlov template class IT3<TestClass::protectedStaticInt>;
118638dcea0SAlex Orlov template struct IT4<&TestClass::protectedFunc>;
119638dcea0SAlex Orlov template class IT4<&TestClass::protectedFuncOverloaded>;
120638dcea0SAlex Orlov template class IT5<&TestClass::protectedStaticFunc>;
121638dcea0SAlex Orlov template class IT5<&TestClass::protectedStaticFuncOverloaded>;
122638dcea0SAlex Orlov template class IT6<TestClass::ProtectedClass>::template NIT1<TestClass::ProtectedClass>;
123638dcea0SAlex Orlov template class IT7<TestClass::AliasProtectedClass, TestClass::ProtectedClass>;
124638dcea0SAlex Orlov template struct IT7<TestClass::ProtectedClass, TestClass::TemplateProtectedClass<TestClass::ProtectedClass>>;
125638dcea0SAlex Orlov template class IT8<&TestClass::protectedFunc, TestClass::protectedStaticInt>;
126638dcea0SAlex Orlov template class IT8<&TestClass::protectedFuncOverloaded, TestClass::protectedStaticInt>;
127638dcea0SAlex Orlov template class IT9<TestClass::ProtectedClass, &TestClass::protectedStaticFunc>;
128638dcea0SAlex Orlov template class IT9<TestClass::ProtectedClass, &TestClass::protectedStaticFuncOverloaded>;
129638dcea0SAlex Orlov template class IT9<TestClass::ProtectedClass, &globalFunction>;
130638dcea0SAlex Orlov 
131638dcea0SAlex Orlov // private
132638dcea0SAlex Orlov template class IT1<TestClass::PrivateClass>;
133638dcea0SAlex Orlov template struct IT1<TestClass::TemplatePrivateClass<int>>;
134638dcea0SAlex Orlov template class IT1<TestClass::AliasPrivateClass>;
135638dcea0SAlex Orlov template struct IT2<TestClass::PrivateClass, TestClass::PrivateClass>;
136638dcea0SAlex Orlov template class IT3<TestClass::privateStaticInt>;
137638dcea0SAlex Orlov template struct IT4<&TestClass::privateFunc>;
138638dcea0SAlex Orlov template class IT4<&TestClass::privateFuncOverloaded>;
139638dcea0SAlex Orlov template class IT5<&TestClass::privateStaticFunc>;
140638dcea0SAlex Orlov template class IT5<&TestClass::privateStaticFuncOverloaded>;
141638dcea0SAlex Orlov template class IT6<TestClass::PrivateClass>::template NIT1<TestClass::PrivateClass>;
142638dcea0SAlex Orlov template class IT7<TestClass::AliasPrivateClass, TestClass::PrivateClass>;
143638dcea0SAlex Orlov template struct IT7<TestClass::PrivateClass, TestClass::TemplatePrivateClass<TestClass::PrivateClass>>;
144638dcea0SAlex Orlov template class IT8<&TestClass::privateFunc, TestClass::privateStaticInt>;
145638dcea0SAlex Orlov template class IT8<&TestClass::privateFuncOverloaded, TestClass::privateStaticInt>;
146638dcea0SAlex Orlov template class IT9<TestClass::PrivateClass, &TestClass::privateStaticFunc>;
147638dcea0SAlex Orlov template class IT9<TestClass::PrivateClass, &TestClass::privateStaticFuncOverloaded>;
148638dcea0SAlex Orlov template class IT9<TestClass::PrivateClass, &globalFunction>;
149638dcea0SAlex Orlov 
150638dcea0SAlex Orlov //----------------------------------------------------------//
151638dcea0SAlex Orlov 
152638dcea0SAlex Orlov // template declarations for full specializations
153638dcea0SAlex Orlov template <typename T> class CT1 {};
154638dcea0SAlex Orlov template <typename T1, typename T2> class CT2 {};
155638dcea0SAlex Orlov template <int X> class CT3 {};
156638dcea0SAlex Orlov template <void (TestClass::*)()> class CT4 {};
157638dcea0SAlex Orlov template <void (*)()> class CT5 {};
158638dcea0SAlex Orlov template <typename T> class CT6 {
159638dcea0SAlex Orlov   template <typename NT> class NCT1 {};
160638dcea0SAlex Orlov   template <typename NT> class NCT2; // forward declaration
161638dcea0SAlex Orlov };
162638dcea0SAlex Orlov 
163638dcea0SAlex Orlov // full specializations
164638dcea0SAlex Orlov 
165638dcea0SAlex Orlov // public
166638dcea0SAlex Orlov template <> class CT1<TestClass::PublicClass>;
167638dcea0SAlex Orlov template <typename T> class CT1<TestClass::TemplatePublicClass<T>>; // not full but let it be here
168638dcea0SAlex Orlov template <> struct CT1<TestClass::TemplatePublicClass<int>>;
169638dcea0SAlex Orlov template <> class CT1<TestClass::AliasPublicClass>;
170638dcea0SAlex Orlov template <> struct CT2<TestClass::PublicClass, TestClass::PublicClass>;
171638dcea0SAlex Orlov template <> class CT3<TestClass::publicStaticInt>;
172638dcea0SAlex Orlov template <> struct CT4<&TestClass::publicFunc>;
173638dcea0SAlex Orlov template <> class CT4<&TestClass::publicFuncOverloaded>;
174638dcea0SAlex Orlov template <> struct CT5<&TestClass::publicStaticFunc>;
175638dcea0SAlex Orlov template <> class CT5<&TestClass::publicStaticFuncOverloaded>;
176638dcea0SAlex Orlov template <> class CT5<&globalFunction>;
177638dcea0SAlex Orlov template <> template <> class CT6<TestClass::PublicClass>::NCT1<TestClass::PublicClass>;
178638dcea0SAlex Orlov 
179638dcea0SAlex Orlov template <> class CT1<TestClass::PublicClass> final {};
180638dcea0SAlex Orlov template <typename T> class CT1<TestClass::TemplatePublicClass<T>> {};
181638dcea0SAlex Orlov template <> class CT1<TestClass::TemplatePublicClass<int>> final {};
182638dcea0SAlex Orlov template <> class CT1<TestClass::AliasPublicClass> {};
183638dcea0SAlex Orlov template <> class CT2<TestClass::PublicClass, TestClass::PublicClass> final {};
184638dcea0SAlex Orlov template <> class CT3<TestClass::publicStaticInt> {};
185638dcea0SAlex Orlov template <> class CT4<&TestClass::publicFunc> final {};
186638dcea0SAlex Orlov template <> class CT4<&TestClass::publicFuncOverloaded> {};
187638dcea0SAlex Orlov template <> class CT5<&TestClass::publicStaticFunc> final {};
188638dcea0SAlex Orlov template <> class CT5<&TestClass::publicStaticFuncOverloaded> {};
189638dcea0SAlex Orlov template <> class CT5<&globalFunction> final {};
190638dcea0SAlex Orlov template <> template <> class CT6<TestClass::PublicClass>::NCT1<TestClass::PublicClass> {};
191638dcea0SAlex Orlov template <> template <typename NT> class CT6<TestClass::PublicClass>::NCT2 final {}; // declaration
192638dcea0SAlex Orlov 
193638dcea0SAlex Orlov // protected
194638dcea0SAlex Orlov template <> class CT1<TestClass::ProtectedClass>;
195638dcea0SAlex Orlov template <typename T> class CT1<TestClass::TemplateProtectedClass<T>>; // not full but let it be here
196638dcea0SAlex Orlov template <> class CT1<TestClass::TemplateProtectedClass<int>>;
197638dcea0SAlex Orlov template <> struct CT1<TestClass::AliasProtectedClass>;
198638dcea0SAlex Orlov template <> class CT2<TestClass::ProtectedClass, TestClass::ProtectedClass>;
199638dcea0SAlex Orlov template <> struct CT3<TestClass::protectedStaticInt>;
200638dcea0SAlex Orlov template <> class CT4<&TestClass::protectedFunc>;
201638dcea0SAlex Orlov template <> struct CT4<&TestClass::protectedFuncOverloaded>;
202638dcea0SAlex Orlov template <> class CT5<&TestClass::protectedStaticFunc>;
203638dcea0SAlex Orlov template <> class CT5<&TestClass::protectedStaticFuncOverloaded>;
204638dcea0SAlex Orlov template <> template <> class CT6<TestClass::ProtectedClass>::NCT1<TestClass::ProtectedClass>;
205638dcea0SAlex Orlov 
206638dcea0SAlex Orlov template <> class CT1<TestClass::ProtectedClass> {};
207638dcea0SAlex Orlov template <typename T> class CT1<TestClass::TemplateProtectedClass<T>> final {}; // not full but let it be here
208638dcea0SAlex Orlov template <> class CT1<TestClass::TemplateProtectedClass<int>> {};
209638dcea0SAlex Orlov template <> class CT1<TestClass::AliasProtectedClass> final {};
210638dcea0SAlex Orlov template <> class CT2<TestClass::ProtectedClass, TestClass::ProtectedClass> {};
211638dcea0SAlex Orlov template <> class CT3<TestClass::protectedStaticInt> final {};
212638dcea0SAlex Orlov template <> class CT4<&TestClass::protectedFunc> {};
213638dcea0SAlex Orlov template <> class CT4<&TestClass::protectedFuncOverloaded> final {};
214638dcea0SAlex Orlov template <> class CT5<&TestClass::protectedStaticFunc> {};
215638dcea0SAlex Orlov template <> class CT5<&TestClass::protectedStaticFuncOverloaded> final {};
216638dcea0SAlex Orlov template <> template <> class CT6<TestClass::ProtectedClass>::NCT1<TestClass::ProtectedClass> {};
217638dcea0SAlex Orlov template <> template <typename NT> class CT6<TestClass::ProtectedClass>::NCT2 final {}; // declaration
218638dcea0SAlex Orlov 
219638dcea0SAlex Orlov // private
220638dcea0SAlex Orlov template <> class CT1<TestClass::PrivateClass>;
221638dcea0SAlex Orlov template <typename T> class CT1<TestClass::TemplatePrivateClass<T>>; // not full but let it be here
222638dcea0SAlex Orlov template <> struct CT1<TestClass::TemplatePrivateClass<int>>;
223638dcea0SAlex Orlov template <> class CT1<TestClass::AliasPrivateClass>;
224638dcea0SAlex Orlov template <> struct CT2<TestClass::PrivateClass, TestClass::PrivateClass>;
225638dcea0SAlex Orlov template <> class CT3<TestClass::privateStaticInt>;
226638dcea0SAlex Orlov template <> struct CT4<&TestClass::privateFunc>;
227638dcea0SAlex Orlov template <> class CT4<&TestClass::privateFuncOverloaded>;
228638dcea0SAlex Orlov template <> class CT5<&TestClass::privateStaticFunc>;
229638dcea0SAlex Orlov template <> class CT5<&TestClass::privateStaticFuncOverloaded>;
230638dcea0SAlex Orlov template <> template <> class CT6<TestClass::PrivateClass>::NCT1<TestClass::PrivateClass>;
231638dcea0SAlex Orlov 
232638dcea0SAlex Orlov template <> class CT1<TestClass::PrivateClass> final {};
233638dcea0SAlex Orlov template <typename T> class CT1<TestClass::TemplatePrivateClass<T>> {}; // not full but let it be here
234638dcea0SAlex Orlov template <> class CT1<TestClass::TemplatePrivateClass<int>> final {};
235638dcea0SAlex Orlov template <> class CT1<TestClass::AliasPrivateClass> {};
236638dcea0SAlex Orlov template <> class CT2<TestClass::PrivateClass, TestClass::PrivateClass> final {};
237638dcea0SAlex Orlov template <> class CT3<TestClass::privateStaticInt> {};
238638dcea0SAlex Orlov template <> class CT4<&TestClass::privateFunc> final {};     // PR37424
239638dcea0SAlex Orlov template <> class CT4<&TestClass::privateFuncOverloaded> {}; // PR37424
240638dcea0SAlex Orlov template <> class CT5<&TestClass::privateStaticFunc> final {};
241638dcea0SAlex Orlov template <> class CT5<&TestClass::privateStaticFuncOverloaded> {};
242638dcea0SAlex Orlov template <> template <> class CT6<TestClass::PrivateClass>::NCT1<TestClass::PrivateClass> final {};
243638dcea0SAlex Orlov template <> template <typename NT> class CT6<TestClass::PrivateClass>::NCT2 {}; // declaration
244638dcea0SAlex Orlov 
245638dcea0SAlex Orlov //----------------------------------------------------------//
246638dcea0SAlex Orlov 
247638dcea0SAlex Orlov // template declarations for full specializations with parents
248638dcea0SAlex Orlov class P1 {};
249638dcea0SAlex Orlov template <typename T> class PCT1 {};
250638dcea0SAlex Orlov template <typename T1, typename T2> class PCT2 {};
251638dcea0SAlex Orlov template <int X> class PCT3 {};
252638dcea0SAlex Orlov template <void (TestClass::*)()> class PCT4 {};
253638dcea0SAlex Orlov template <void (*)()> class PCT5 {};
254638dcea0SAlex Orlov template <typename T> class PCT6 {
255638dcea0SAlex Orlov   // expected-note@+1 3{{implicitly declared private here}}
256638dcea0SAlex Orlov   template <typename NT> class NPCT1 {};
257638dcea0SAlex Orlov   // expected-note@+1 {{template is declared here}}
258638dcea0SAlex Orlov   template <typename NT> class NPCT2; // forward declaration
259638dcea0SAlex Orlov };
260638dcea0SAlex Orlov 
261638dcea0SAlex Orlov // full specializations with parents
262638dcea0SAlex Orlov 
263638dcea0SAlex Orlov // protected + public
264638dcea0SAlex Orlov template <> class PCT1<TestClass::PublicClass> : P1 {};
265638dcea0SAlex Orlov template <typename T> class PCT1<TestClass::TemplatePublicClass<T>> : PCT2<TestClass::PublicClass, TestClass::PublicClass> {}; // not full but let it be here
266638dcea0SAlex Orlov template <> struct PCT1<TestClass::TemplatePublicClass<int>> : PCT1<TestClass::AliasPublicClass> {};
267638dcea0SAlex Orlov template <> class PCT1<TestClass::AliasProtectedClass> : PCT2<TestClass::PublicClass, int> {};
268638dcea0SAlex Orlov template <> struct PCT2<TestClass::ProtectedClass, TestClass::PublicClass> : PCT3<TestClass::publicStaticInt> {};
269638dcea0SAlex Orlov template <> class PCT3<TestClass::protectedStaticInt> : PCT4<&TestClass::publicFunc> {};
270638dcea0SAlex Orlov template <> struct PCT4<&TestClass::protectedFunc> : PCT5<&TestClass::publicStaticFunc> {};
271638dcea0SAlex Orlov template <> class PCT4<&TestClass::publicFuncOverloaded> : PCT5<&TestClass::publicStaticFuncOverloaded> {};
272638dcea0SAlex Orlov template <> class PCT5<&TestClass::protectedStaticFunc> : PCT5<&TestClass::publicStaticFuncOverloaded> {};
273638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
274638dcea0SAlex Orlov template <> class PCT5<&TestClass::protectedStaticFuncOverloaded> : PCT6<TestClass::PublicClass>::NPCT1<TestClass::PublicClass> {};
275638dcea0SAlex Orlov // expected-error@+2 {{is a protected member of}}
276638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
277638dcea0SAlex Orlov template <> class PCT5<&globalFunction> : PCT6<TestClass::ProtectedClass>::NPCT1<int> {};
278638dcea0SAlex Orlov template <> template <typename NT> class PCT6<TestClass::PublicClass>::NPCT2 : P1 {}; // declaration
279638dcea0SAlex Orlov template <> template <> class PCT6<TestClass::PublicClass>::NPCT1<TestClass::ProtectedClass> : PCT6<TestClass::PublicClass>::template NPCT2<int> {};
280638dcea0SAlex Orlov 
281638dcea0SAlex Orlov // protected + private
282638dcea0SAlex Orlov template <> class PCT1<TestClass::PrivateClass> : P1 {};
283638dcea0SAlex Orlov // expected-error@+2 {{is a protected member of}}
284638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
285638dcea0SAlex Orlov template <typename T> class PCT1<TestClass::TemplatePrivateClass<T>> : PCT2<TestClass::PrivateClass, TestClass::ProtectedClass> {}; // not full but let it be here
286638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
287638dcea0SAlex Orlov template <> class PCT1<TestClass::TemplatePrivateClass<int>> : PCT1<TestClass::AliasProtectedClass> {};
288638dcea0SAlex Orlov // expected-error@+2 {{is a protected member of}}
289638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
290638dcea0SAlex Orlov template <> class PCT1<TestClass::AliasPrivateClass> : PCT2<TestClass::ProtectedClass, TestClass::PrivateClass> {};
291638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
292638dcea0SAlex Orlov template <> class PCT2<TestClass::PrivateClass, TestClass::PrivateClass> : PCT3<TestClass::protectedStaticInt> {};
293638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
294638dcea0SAlex Orlov template <> class PCT3<TestClass::privateStaticInt> : PCT4<&TestClass::protectedFunc> {};
295638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
296638dcea0SAlex Orlov template <> class PCT4<&TestClass::privateFunc> : PCT5<&TestClass::protectedStaticFunc> {};
297638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
298638dcea0SAlex Orlov template <> class PCT4<&TestClass::privateFuncOverloaded> : PCT5<&TestClass::protectedStaticFuncOverloaded> {};
299638dcea0SAlex Orlov template <> class PCT5<&TestClass::privateStaticFunc> : P1 {};
300638dcea0SAlex Orlov // expected-error@+2 {{implicit instantiation of undefined template}}
301638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
302638dcea0SAlex Orlov template <> template <> class PCT6<TestClass::PrivateClass>::NPCT1<TestClass::PrivateClass> : PCT6<TestClass::PrivateClass>::NPCT2<int> {};
303638dcea0SAlex Orlov // expected-error@+1 3{{is a private member of}}
304638dcea0SAlex Orlov template <> class PCT5<&TestClass::privateStaticFuncOverloaded> : PCT6<TestClass::PrivateClass>::NPCT1<TestClass::PrivateClass> {};
305638dcea0SAlex Orlov template <> template <typename NT> class PCT6<TestClass::PrivateClass>::NPCT2 : P1 {}; // declaration
306638dcea0SAlex Orlov 
307638dcea0SAlex Orlov //----------------------------------------------------------//
308638dcea0SAlex Orlov 
309638dcea0SAlex Orlov // template declarations for partial specializations
310638dcea0SAlex Orlov template <typename T1, typename T2> class CTT1 {};
311638dcea0SAlex Orlov template <typename T1, typename T2, typename T3> class CTT2 {};
312638dcea0SAlex Orlov template <typename T, int X> class CTT3 {};
313638dcea0SAlex Orlov template <typename T, void (TestClass::*)()> class CTT4 {};
314638dcea0SAlex Orlov template <typename T, void (*)()> class CTT5 {};
315638dcea0SAlex Orlov template <typename T1, typename T2> class CTT6 {
316638dcea0SAlex Orlov   template <typename NT> class NCT1 {};
317638dcea0SAlex Orlov   template <typename NT> class NCT2; // forward declaration
318638dcea0SAlex Orlov   template <typename NT1, typename NT2> class NCT3 {};
319638dcea0SAlex Orlov   template <typename NT1, typename NT2> class NCT4; // forward declaration
320638dcea0SAlex Orlov };
321638dcea0SAlex Orlov 
322638dcea0SAlex Orlov // partial specializations
323638dcea0SAlex Orlov 
324638dcea0SAlex Orlov // public
325638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::PublicClass> final {};
326638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::TemplatePublicClass<T>> {};
327638dcea0SAlex Orlov template <typename T> struct CTT1<T, TestClass::TemplatePublicClass<int>> final {};
328638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::AliasPublicClass> {};
329638dcea0SAlex Orlov template <typename T> struct CTT2<T, TestClass::PublicClass, TestClass::PublicClass> final {};
330638dcea0SAlex Orlov template <typename T> struct CTT2<TestClass::PublicClass, T, TestClass::PublicClass> {};
331638dcea0SAlex Orlov template <typename T> class CTT2<TestClass::PublicClass, TestClass::PublicClass, T> final {};
332638dcea0SAlex Orlov template <typename T> class CTT3<T, TestClass::publicStaticInt> {};
333638dcea0SAlex Orlov template <typename T> class CTT4<T, &TestClass::publicFunc> final {};
334638dcea0SAlex Orlov template <typename T> class CTT4<T, &TestClass::publicFuncOverloaded> {};
335638dcea0SAlex Orlov template <typename T> class CTT5<T, &TestClass::publicStaticFunc> final {};
336638dcea0SAlex Orlov template <typename T> class CTT5<T, &TestClass::publicStaticFuncOverloaded> {};
337638dcea0SAlex Orlov template <typename T> class CTT5<T, &globalFunction> final {};
338638dcea0SAlex Orlov // expected-error@+1 {{cannot specialize a dependent template}}
339638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<T1, TestClass::PublicClass>::template NCT1<T2 *> {};
340638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT1<T3 *> final {};
341638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT2 {}; // declaration
342638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT2<T3 *> final {};
343638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::PublicClass> {};
344638dcea0SAlex Orlov // expected-error@+1 {{cannot specialize a dependent template}}
345638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<T1, TestClass::PublicClass>::template NCT3<T2, TestClass::PublicClass> final {};
346638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3, typename T4> class CTT6<T1, T2>::NCT4 {}; // declaration
347638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::PublicClass> final {};
348638dcea0SAlex Orlov template <typename T> class CTT6<TestClass::PublicClass, T> {
349638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT3 {};
350638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT4;
351638dcea0SAlex Orlov };
352638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<TestClass::PublicClass, T1>::NCT3<T2, TestClass::PublicClass> {};
353638dcea0SAlex Orlov template <typename T1> template <typename, typename> class CTT6<TestClass::PublicClass, T1>::NCT4 final {};
354638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<TestClass::PublicClass, T1>::NCT4<T2, TestClass::PublicClass> {};
355638dcea0SAlex Orlov 
356638dcea0SAlex Orlov // protected
357638dcea0SAlex Orlov 
358638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::ProtectedClass> {};
359638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::TemplateProtectedClass<T>> final {};
360638dcea0SAlex Orlov template <typename T> struct CTT1<T, TestClass::TemplateProtectedClass<int>> {};
361638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::AliasProtectedClass> final {};
362638dcea0SAlex Orlov template <typename T> struct CTT2<T, TestClass::ProtectedClass, TestClass::ProtectedClass> {};
363638dcea0SAlex Orlov template <typename T> class CTT2<TestClass::ProtectedClass, T, TestClass::ProtectedClass> final {};
364638dcea0SAlex Orlov template <typename T> struct CTT2<TestClass::ProtectedClass, TestClass::ProtectedClass, T> {};
365638dcea0SAlex Orlov template <typename T> class CTT3<T, TestClass::protectedStaticInt> final {};
366638dcea0SAlex Orlov template <typename T> class CTT4<T, &TestClass::protectedFunc> {};
367638dcea0SAlex Orlov template <typename T> class CTT4<T, &TestClass::protectedFuncOverloaded> final {};
368638dcea0SAlex Orlov template <typename T> class CTT5<T, &TestClass::protectedStaticFunc> {};
369638dcea0SAlex Orlov template <typename T> class CTT5<T, &TestClass::protectedStaticFuncOverloaded> final {};
370638dcea0SAlex Orlov // expected-error@+1 {{cannot specialize a dependent template}}
371638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<T1, TestClass::ProtectedClass>::template NCT1<T2 *> {};
372638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::ProtectedClass> final {};
373638dcea0SAlex Orlov // expected-error@+1 {{cannot specialize a dependent template}}
374638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<T1, TestClass::ProtectedClass>::template NCT3<T2, TestClass::ProtectedClass> {};
375638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::ProtectedClass> final {};
376638dcea0SAlex Orlov template <typename T> class CTT6<TestClass::ProtectedClass, T> {
377638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT3 {};
378638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT4;
379638dcea0SAlex Orlov };
380638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<TestClass::ProtectedClass, T1>::NCT3<T2, TestClass::ProtectedClass> final {};
381638dcea0SAlex Orlov template <typename T1> template <typename, typename> class CTT6<TestClass::ProtectedClass, T1>::NCT4 {};
382638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<TestClass::ProtectedClass, T1>::NCT4<T2, TestClass::ProtectedClass> final {};
383638dcea0SAlex Orlov 
384638dcea0SAlex Orlov // private
385638dcea0SAlex Orlov 
386638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::PrivateClass> final {};
387638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::TemplatePrivateClass<T>> {};
388638dcea0SAlex Orlov template <typename T> struct CTT1<T, TestClass::TemplatePrivateClass<int>> final {};
389638dcea0SAlex Orlov template <typename T> class CTT1<T, TestClass::AliasPrivateClass> {};
390638dcea0SAlex Orlov template <typename T> struct CTT2<T, TestClass::PrivateClass, TestClass::PrivateClass> final {};
391638dcea0SAlex Orlov template <typename T> class CTT2<TestClass::PrivateClass, T, TestClass::PrivateClass> {};
392638dcea0SAlex Orlov template <typename T> struct CTT2<TestClass::PrivateClass, TestClass::PrivateClass, T> final {};
393638dcea0SAlex Orlov template <typename T> class CTT3<T, TestClass::privateStaticInt> {};
394638dcea0SAlex Orlov template <typename T> class CTT4<T, &TestClass::privateFunc> final {};
395638dcea0SAlex Orlov template <typename T> class CTT4<T, &TestClass::privateFuncOverloaded> {};
396638dcea0SAlex Orlov template <typename T> class CTT5<T, &TestClass::privateStaticFunc> final {};
397638dcea0SAlex Orlov template <typename T> class CTT5<T, &TestClass::privateStaticFuncOverloaded> {};
398638dcea0SAlex Orlov // expected-error@+1 {{cannot specialize a dependent template}}
399638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<T1, TestClass::PrivateClass>::template NCT1<T2 *> final {};
400638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::PrivateClass> {};
401638dcea0SAlex Orlov // expected-error@+1 {{cannot specialize a dependent template}}
402638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<T1, TestClass::PrivateClass>::template NCT3<T2, TestClass::PrivateClass> final {};
403638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::PrivateClass> {};
404638dcea0SAlex Orlov template <typename T> class CTT6<TestClass::PrivateClass, T> {
405638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT3 {};
406638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT4;
407638dcea0SAlex Orlov };
408638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<TestClass::PrivateClass, T1>::NCT3<T2, TestClass::PrivateClass> {};
409638dcea0SAlex Orlov template <typename T1> template <typename, typename> class CTT6<TestClass::PrivateClass, T1>::NCT4 final {};
410638dcea0SAlex Orlov template <typename T1> template <typename T2> class CTT6<TestClass::PrivateClass, T1>::NCT4<T2, TestClass::PrivateClass> final {};
411638dcea0SAlex Orlov 
412638dcea0SAlex Orlov //----------------------------------------------------------//
413638dcea0SAlex Orlov 
414638dcea0SAlex Orlov // template declarations for partial specializations with parents
415638dcea0SAlex Orlov template <typename T1, typename T2> class PCTT1 {};
416638dcea0SAlex Orlov template <typename T1, typename T2, typename T3> class PCTT2 {};
417638dcea0SAlex Orlov template <typename T, int X> class PCTT3 {};
418638dcea0SAlex Orlov template <typename T, void (TestClass::*)()> class PCTT4 {};
419638dcea0SAlex Orlov template <typename T, void (*)()> class PCTT5 {};
420638dcea0SAlex Orlov template <typename T1, typename T2> class PCTT6 {
421638dcea0SAlex Orlov   template <typename NT> class NCT1 {};
422638dcea0SAlex Orlov   template <typename NT> class NCT2; // forward declaration
423638dcea0SAlex Orlov   template <typename NT1, typename NT2> class NCT3 {};
424638dcea0SAlex Orlov   template <typename NT1, typename NT2> class NCT4; // forward declaration
425638dcea0SAlex Orlov };
426638dcea0SAlex Orlov 
427638dcea0SAlex Orlov // partial specializations with parents
428638dcea0SAlex Orlov 
429638dcea0SAlex Orlov // protected + public
430638dcea0SAlex Orlov template <typename T> class PCTT1<T, TestClass::PublicClass> : P1 {};
431638dcea0SAlex Orlov template <typename T> struct PCTT1<T, TestClass::TemplatePublicClass<T>> final : PCTT2<T, TestClass::PublicClass, TestClass::PublicClass> {}; // not full but let it be here
432638dcea0SAlex Orlov template <typename T> class PCTT1<T, TestClass::TemplatePublicClass<int>> : PCTT1<T, TestClass::AliasPublicClass> {};
433638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
434638dcea0SAlex Orlov template <typename T> class PCTT1<T, TestClass::TemplatePublicClass<TestClass::TemplateProtectedClass<T>>> final : PCTT1<T, TestClass::ProtectedClass> {};
435638dcea0SAlex Orlov template <typename T> struct PCTT1<T, TestClass::AliasProtectedClass> : PCTT2<T, TestClass::PublicClass, int> {};
436638dcea0SAlex Orlov template <typename T> class PCTT2<T, TestClass::ProtectedClass, TestClass::PublicClass> final : PCTT3<T, TestClass::publicStaticInt> {};
437638dcea0SAlex Orlov template <typename T> class PCTT3<T, TestClass::protectedStaticInt> : PCTT4<T, &TestClass::publicFunc> {};
438638dcea0SAlex Orlov template <typename T> struct PCTT4<T, &TestClass::protectedFunc> final : PCTT5<T, &TestClass::publicStaticFunc> {};
439638dcea0SAlex Orlov template <typename T> class PCTT4<T, &TestClass::publicFuncOverloaded> : PCTT5<T, &TestClass::publicStaticFuncOverloaded> {};
440638dcea0SAlex Orlov template <typename T> class PCTT5<T, &TestClass::protectedStaticFunc> final : PCTT5<T, &TestClass::publicStaticFuncOverloaded> {};
441638dcea0SAlex Orlov template <typename T> class PCTT5<T, &TestClass::protectedStaticFuncOverloaded> : PCTT6<T, TestClass::PublicClass>::template NCT1<TestClass::PublicClass> {};
442638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
443638dcea0SAlex Orlov template <typename T> class PCTT5<T, &globalFunction> : PCTT6<T, TestClass::ProtectedClass>::template NCT1<int> {};
444638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
445638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class PCTT6<T1, T2>::NCT2 final : PCTT4<T1, &TestClass::protectedFunc> {}; // declaration
446638dcea0SAlex Orlov template <typename T1, typename T2> template <typename T3> class PCTT6<T1, T2>::NCT2<T3 *> : P1 {};
447638dcea0SAlex Orlov // expected-error@+2 {{cannot specialize a dependent template}}
448638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
449638dcea0SAlex Orlov template <typename T> template <typename NT> class PCTT6<T, TestClass::ProtectedClass>::template NCT1<NT *> : PCTT6<T, TestClass::ProtectedClass>::template NCT2<int> {};
450638dcea0SAlex Orlov 
451638dcea0SAlex Orlov // protected + private
452638dcea0SAlex Orlov template <typename T> class PCTT1<T, TestClass::PrivateClass> : P1 {};
453638dcea0SAlex Orlov // expected-error@+2 {{is a protected member of}}
454638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
455638dcea0SAlex Orlov template <typename T> struct PCTT1<T, TestClass::TemplatePrivateClass<T>> final : PCTT2<T, TestClass::PrivateClass, TestClass::ProtectedClass> {}; // not full but let it be here
456638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
457638dcea0SAlex Orlov template <typename T> class PCTT1<T, TestClass::TemplatePrivateClass<int>> : PCTT1<T, TestClass::AliasProtectedClass> {};
458638dcea0SAlex Orlov // expected-error@+2 {{is a protected member of}}
459638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
460638dcea0SAlex Orlov template <typename T> struct PCTT1<T, TestClass::AliasPrivateClass> final : PCTT2<T, TestClass::ProtectedClass, TestClass::PrivateClass> {};
461638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
462638dcea0SAlex Orlov template <typename T> class PCTT2<T, TestClass::PrivateClass, TestClass::TemplatePrivateClass<T>> : PCTT3<T, TestClass::protectedStaticInt> {};
463638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
464638dcea0SAlex Orlov template <typename T> class PCTT3<T, TestClass::privateStaticInt> final : PCTT4<T, &TestClass::protectedFunc> {};
465638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
466638dcea0SAlex Orlov template <typename T> struct PCTT4<T, &TestClass::privateFunc> : PCTT5<T, &TestClass::protectedStaticFunc> {};
467638dcea0SAlex Orlov // expected-error@+1 {{is a protected member of}}
468638dcea0SAlex Orlov template <typename T> class PCTT4<T, &TestClass::privateFuncOverloaded> final : PCTT5<T, &TestClass::protectedStaticFuncOverloaded> {};
469638dcea0SAlex Orlov template <typename T> class PCTT5<T, &TestClass::privateStaticFunc> : P1 {};
470638dcea0SAlex Orlov // expected-error@+2 {{cannot specialize a dependent template}}
471638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
472638dcea0SAlex Orlov template <typename T> class PCTT6<T, TestClass::PrivateClass>::template PCTT1<TestClass::PrivateClass> : PCTT6<T, TestClass::PrivateClass>::template NCT2<int> {};
473638dcea0SAlex Orlov // expected-error@+1 {{is a private member of}}
474638dcea0SAlex Orlov template <typename T> class PCTT5<T, &TestClass::privateStaticFuncOverloaded> final : PCTT6<T, T>::template NCT1<TestClass::PrivateClass> {};
475638dcea0SAlex Orlov template <typename T> class PCTT6<TestClass::PrivateClass, T> {
476638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT3 final {};
477638dcea0SAlex Orlov   template <typename T1, typename T2> class NCT4;
478638dcea0SAlex Orlov };
479638dcea0SAlex Orlov template <typename T1> template <typename, typename> class PCTT6<TestClass::PrivateClass, T1>::NCT4 final {};
480638dcea0SAlex Orlov // expected-error@+1 2{{is a private member of}}
481*1156bbc5SKrystian Stasiowski template <typename T1> template <typename T2> struct PCTT6<TestClass::PrivateClass, T1>::NCT3<T2, TestClass::TemplatePrivateClass<TestClass::TemplateProtectedClass<TestClass::PublicClass>>> : PCTT6<TestClass::PrivateClass, T1>::NCT4<T2, TestClass::TemplatePrivateClass<int>> {};
482