482 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3// C++20 [temp.class.spec] 13.7.5/104// The usual access checking rules do not apply to non-dependent names5// used to specify template arguments of the simple-template-id of the6// partial specialization.7//8// C++20 [temp.spec] 13.9/6:9// The usual access checking rules do not apply to names in a declaration10// of an explicit instantiation or explicit specialization...11 12// TODO: add test cases for `enum`13 14// class for tests15class TestClass {16public:17 class PublicClass {};18 template <class T> class TemplatePublicClass {};19 20 using AliasPublicClass = unsigned char;21 22 void publicFunc();23 void publicFuncOverloaded();24 void publicFuncOverloaded(int);25 26 static void publicStaticFunc();27 static void publicStaticFuncOverloaded();28 static void publicStaticFuncOverloaded(int);29 30 static constexpr int publicStaticInt = 42;31 32protected:33 // expected-note@+1 8{{declared protected here}}34 class ProtectedClass {};35 template <class T> class TemplateProtectedClass {};36 37 // expected-note@+1 2{{declared protected here}}38 using AliasProtectedClass = const char;39 40 // expected-note@+1 3{{declared protected here}}41 void protectedFunc();42 void protectedFuncOverloaded();43 void protectedFuncOverloaded(int);44 45 // expected-note@+1 2{{declared protected here}}46 static void protectedStaticFunc();47 // expected-note@+1 2{{declared protected here}}48 static void protectedStaticFuncOverloaded();49 static void protectedStaticFuncOverloaded(int);50 51 // expected-note@+1 2{{declared protected here}}52 static constexpr int protectedStaticInt = 43;53 54private:55 // expected-note@+1 10{{declared private here}}56 class PrivateClass {};57 // expected-note@+1 {{declared private here}}58 template <class T> class TemplatePrivateClass {};59 60 using AliasPrivateClass = char *;61 62 void privateFunc();63 void privateFuncOverloaded();64 void privateFuncOverloaded(int);65 66 static void privateStaticFunc();67 static void privateStaticFuncOverloaded();68 static void privateStaticFuncOverloaded(int);69 70 static constexpr int privateStaticInt = 44;71};72 73void globalFunction() {}74 75//----------------------------------------------------------//76 77// template declarations for explicit instantiations78template <typename T> class IT1 {};79template <typename T1, typename T2> class IT2 {};80template <int X> class IT3 {};81template <void (TestClass::*)()> class IT4 {};82template <void (*)()> class IT5 {};83template <typename T> class IT6 {84 template <typename NT> class NIT1 {};85};86template <typename T1, typename T2> class IT7 {};87template <void (TestClass::*)(), int X> class IT8 {};88template <typename T, void (*)()> class IT9 {};89 90// explicit instantiations91 92// public93template class IT1<TestClass::PublicClass>;94template struct IT1<TestClass::TemplatePublicClass<int>>;95template class IT1<TestClass::AliasPublicClass>;96template struct IT2<TestClass::PublicClass, TestClass::PublicClass>;97template class IT3<TestClass::publicStaticInt>;98template struct IT4<&TestClass::publicFunc>;99template class IT4<&TestClass::publicFuncOverloaded>;100template class IT5<&TestClass::publicStaticFunc>;101template class IT5<&TestClass::publicStaticFuncOverloaded>;102template class IT5<&globalFunction>;103template class IT6<TestClass::PublicClass>::template NIT1<TestClass::PublicClass>;104template class IT7<TestClass::AliasPublicClass, TestClass::PublicClass>;105template struct IT7<TestClass::PublicClass, TestClass::TemplatePublicClass<TestClass::PublicClass>>;106template class IT8<&TestClass::publicFunc, TestClass::publicStaticInt>;107template class IT8<&TestClass::publicFuncOverloaded, TestClass::publicStaticInt>;108template class IT9<TestClass::PublicClass, &TestClass::publicStaticFunc>;109template class IT9<TestClass::PublicClass, &TestClass::publicStaticFuncOverloaded>;110template class IT9<TestClass::PublicClass, &globalFunction>;111 112// protected113template class IT1<TestClass::ProtectedClass>;114template struct IT1<TestClass::TemplateProtectedClass<int>>;115template class IT1<TestClass::AliasProtectedClass>;116template struct IT2<TestClass::ProtectedClass, TestClass::ProtectedClass>;117template class IT3<TestClass::protectedStaticInt>;118template struct IT4<&TestClass::protectedFunc>;119template class IT4<&TestClass::protectedFuncOverloaded>;120template class IT5<&TestClass::protectedStaticFunc>;121template class IT5<&TestClass::protectedStaticFuncOverloaded>;122template class IT6<TestClass::ProtectedClass>::template NIT1<TestClass::ProtectedClass>;123template class IT7<TestClass::AliasProtectedClass, TestClass::ProtectedClass>;124template struct IT7<TestClass::ProtectedClass, TestClass::TemplateProtectedClass<TestClass::ProtectedClass>>;125template class IT8<&TestClass::protectedFunc, TestClass::protectedStaticInt>;126template class IT8<&TestClass::protectedFuncOverloaded, TestClass::protectedStaticInt>;127template class IT9<TestClass::ProtectedClass, &TestClass::protectedStaticFunc>;128template class IT9<TestClass::ProtectedClass, &TestClass::protectedStaticFuncOverloaded>;129template class IT9<TestClass::ProtectedClass, &globalFunction>;130 131// private132template class IT1<TestClass::PrivateClass>;133template struct IT1<TestClass::TemplatePrivateClass<int>>;134template class IT1<TestClass::AliasPrivateClass>;135template struct IT2<TestClass::PrivateClass, TestClass::PrivateClass>;136template class IT3<TestClass::privateStaticInt>;137template struct IT4<&TestClass::privateFunc>;138template class IT4<&TestClass::privateFuncOverloaded>;139template class IT5<&TestClass::privateStaticFunc>;140template class IT5<&TestClass::privateStaticFuncOverloaded>;141template class IT6<TestClass::PrivateClass>::template NIT1<TestClass::PrivateClass>;142template class IT7<TestClass::AliasPrivateClass, TestClass::PrivateClass>;143template struct IT7<TestClass::PrivateClass, TestClass::TemplatePrivateClass<TestClass::PrivateClass>>;144template class IT8<&TestClass::privateFunc, TestClass::privateStaticInt>;145template class IT8<&TestClass::privateFuncOverloaded, TestClass::privateStaticInt>;146template class IT9<TestClass::PrivateClass, &TestClass::privateStaticFunc>;147template class IT9<TestClass::PrivateClass, &TestClass::privateStaticFuncOverloaded>;148template class IT9<TestClass::PrivateClass, &globalFunction>;149 150//----------------------------------------------------------//151 152// template declarations for full specializations153template <typename T> class CT1 {};154template <typename T1, typename T2> class CT2 {};155template <int X> class CT3 {};156template <void (TestClass::*)()> class CT4 {};157template <void (*)()> class CT5 {};158template <typename T> class CT6 {159 template <typename NT> class NCT1 {};160 template <typename NT> class NCT2; // forward declaration161};162 163// full specializations164 165// public166template <> class CT1<TestClass::PublicClass>;167template <typename T> class CT1<TestClass::TemplatePublicClass<T>>; // not full but let it be here168template <> struct CT1<TestClass::TemplatePublicClass<int>>;169template <> class CT1<TestClass::AliasPublicClass>;170template <> struct CT2<TestClass::PublicClass, TestClass::PublicClass>;171template <> class CT3<TestClass::publicStaticInt>;172template <> struct CT4<&TestClass::publicFunc>;173template <> class CT4<&TestClass::publicFuncOverloaded>;174template <> struct CT5<&TestClass::publicStaticFunc>;175template <> class CT5<&TestClass::publicStaticFuncOverloaded>;176template <> class CT5<&globalFunction>;177template <> template <> class CT6<TestClass::PublicClass>::NCT1<TestClass::PublicClass>;178 179template <> class CT1<TestClass::PublicClass> final {};180template <typename T> class CT1<TestClass::TemplatePublicClass<T>> {};181template <> class CT1<TestClass::TemplatePublicClass<int>> final {};182template <> class CT1<TestClass::AliasPublicClass> {};183template <> class CT2<TestClass::PublicClass, TestClass::PublicClass> final {};184template <> class CT3<TestClass::publicStaticInt> {};185template <> class CT4<&TestClass::publicFunc> final {};186template <> class CT4<&TestClass::publicFuncOverloaded> {};187template <> class CT5<&TestClass::publicStaticFunc> final {};188template <> class CT5<&TestClass::publicStaticFuncOverloaded> {};189template <> class CT5<&globalFunction> final {};190template <> template <> class CT6<TestClass::PublicClass>::NCT1<TestClass::PublicClass> {};191template <> template <typename NT> class CT6<TestClass::PublicClass>::NCT2 final {}; // declaration192 193// protected194template <> class CT1<TestClass::ProtectedClass>;195template <typename T> class CT1<TestClass::TemplateProtectedClass<T>>; // not full but let it be here196template <> class CT1<TestClass::TemplateProtectedClass<int>>;197template <> struct CT1<TestClass::AliasProtectedClass>;198template <> class CT2<TestClass::ProtectedClass, TestClass::ProtectedClass>;199template <> struct CT3<TestClass::protectedStaticInt>;200template <> class CT4<&TestClass::protectedFunc>;201template <> struct CT4<&TestClass::protectedFuncOverloaded>;202template <> class CT5<&TestClass::protectedStaticFunc>;203template <> class CT5<&TestClass::protectedStaticFuncOverloaded>;204template <> template <> class CT6<TestClass::ProtectedClass>::NCT1<TestClass::ProtectedClass>;205 206template <> class CT1<TestClass::ProtectedClass> {};207template <typename T> class CT1<TestClass::TemplateProtectedClass<T>> final {}; // not full but let it be here208template <> class CT1<TestClass::TemplateProtectedClass<int>> {};209template <> class CT1<TestClass::AliasProtectedClass> final {};210template <> class CT2<TestClass::ProtectedClass, TestClass::ProtectedClass> {};211template <> class CT3<TestClass::protectedStaticInt> final {};212template <> class CT4<&TestClass::protectedFunc> {};213template <> class CT4<&TestClass::protectedFuncOverloaded> final {};214template <> class CT5<&TestClass::protectedStaticFunc> {};215template <> class CT5<&TestClass::protectedStaticFuncOverloaded> final {};216template <> template <> class CT6<TestClass::ProtectedClass>::NCT1<TestClass::ProtectedClass> {};217template <> template <typename NT> class CT6<TestClass::ProtectedClass>::NCT2 final {}; // declaration218 219// private220template <> class CT1<TestClass::PrivateClass>;221template <typename T> class CT1<TestClass::TemplatePrivateClass<T>>; // not full but let it be here222template <> struct CT1<TestClass::TemplatePrivateClass<int>>;223template <> class CT1<TestClass::AliasPrivateClass>;224template <> struct CT2<TestClass::PrivateClass, TestClass::PrivateClass>;225template <> class CT3<TestClass::privateStaticInt>;226template <> struct CT4<&TestClass::privateFunc>;227template <> class CT4<&TestClass::privateFuncOverloaded>;228template <> class CT5<&TestClass::privateStaticFunc>;229template <> class CT5<&TestClass::privateStaticFuncOverloaded>;230template <> template <> class CT6<TestClass::PrivateClass>::NCT1<TestClass::PrivateClass>;231 232template <> class CT1<TestClass::PrivateClass> final {};233template <typename T> class CT1<TestClass::TemplatePrivateClass<T>> {}; // not full but let it be here234template <> class CT1<TestClass::TemplatePrivateClass<int>> final {};235template <> class CT1<TestClass::AliasPrivateClass> {};236template <> class CT2<TestClass::PrivateClass, TestClass::PrivateClass> final {};237template <> class CT3<TestClass::privateStaticInt> {};238template <> class CT4<&TestClass::privateFunc> final {}; // PR37424239template <> class CT4<&TestClass::privateFuncOverloaded> {}; // PR37424240template <> class CT5<&TestClass::privateStaticFunc> final {};241template <> class CT5<&TestClass::privateStaticFuncOverloaded> {};242template <> template <> class CT6<TestClass::PrivateClass>::NCT1<TestClass::PrivateClass> final {};243template <> template <typename NT> class CT6<TestClass::PrivateClass>::NCT2 {}; // declaration244 245//----------------------------------------------------------//246 247// template declarations for full specializations with parents248class P1 {};249template <typename T> class PCT1 {};250template <typename T1, typename T2> class PCT2 {};251template <int X> class PCT3 {};252template <void (TestClass::*)()> class PCT4 {};253template <void (*)()> class PCT5 {};254template <typename T> class PCT6 {255 // expected-note@+1 3{{implicitly declared private here}}256 template <typename NT> class NPCT1 {};257 // expected-note@+1 {{template is declared here}}258 template <typename NT> class NPCT2; // forward declaration259};260 261// full specializations with parents262 263// protected + public264template <> class PCT1<TestClass::PublicClass> : P1 {};265template <typename T> class PCT1<TestClass::TemplatePublicClass<T>> : PCT2<TestClass::PublicClass, TestClass::PublicClass> {}; // not full but let it be here266template <> struct PCT1<TestClass::TemplatePublicClass<int>> : PCT1<TestClass::AliasPublicClass> {};267template <> class PCT1<TestClass::AliasProtectedClass> : PCT2<TestClass::PublicClass, int> {};268template <> struct PCT2<TestClass::ProtectedClass, TestClass::PublicClass> : PCT3<TestClass::publicStaticInt> {};269template <> class PCT3<TestClass::protectedStaticInt> : PCT4<&TestClass::publicFunc> {};270template <> struct PCT4<&TestClass::protectedFunc> : PCT5<&TestClass::publicStaticFunc> {};271template <> class PCT4<&TestClass::publicFuncOverloaded> : PCT5<&TestClass::publicStaticFuncOverloaded> {};272template <> class PCT5<&TestClass::protectedStaticFunc> : PCT5<&TestClass::publicStaticFuncOverloaded> {};273// expected-error@+1 {{is a private member of}}274template <> class PCT5<&TestClass::protectedStaticFuncOverloaded> : PCT6<TestClass::PublicClass>::NPCT1<TestClass::PublicClass> {};275// expected-error@+2 {{is a protected member of}}276// expected-error@+1 {{is a private member of}}277template <> class PCT5<&globalFunction> : PCT6<TestClass::ProtectedClass>::NPCT1<int> {};278template <> template <typename NT> class PCT6<TestClass::PublicClass>::NPCT2 : P1 {}; // declaration279template <> template <> class PCT6<TestClass::PublicClass>::NPCT1<TestClass::ProtectedClass> : PCT6<TestClass::PublicClass>::template NPCT2<int> {};280 281// protected + private282template <> class PCT1<TestClass::PrivateClass> : P1 {};283// expected-error@+2 {{is a protected member of}}284// expected-error@+1 {{is a private member of}}285template <typename T> class PCT1<TestClass::TemplatePrivateClass<T>> : PCT2<TestClass::PrivateClass, TestClass::ProtectedClass> {}; // not full but let it be here286// expected-error@+1 {{is a protected member of}}287template <> class PCT1<TestClass::TemplatePrivateClass<int>> : PCT1<TestClass::AliasProtectedClass> {};288// expected-error@+2 {{is a protected member of}}289// expected-error@+1 {{is a private member of}}290template <> class PCT1<TestClass::AliasPrivateClass> : PCT2<TestClass::ProtectedClass, TestClass::PrivateClass> {};291// expected-error@+1 {{is a protected member of}}292template <> class PCT2<TestClass::PrivateClass, TestClass::PrivateClass> : PCT3<TestClass::protectedStaticInt> {};293// expected-error@+1 {{is a protected member of}}294template <> class PCT3<TestClass::privateStaticInt> : PCT4<&TestClass::protectedFunc> {};295// expected-error@+1 {{is a protected member of}}296template <> class PCT4<&TestClass::privateFunc> : PCT5<&TestClass::protectedStaticFunc> {};297// expected-error@+1 {{is a protected member of}}298template <> class PCT4<&TestClass::privateFuncOverloaded> : PCT5<&TestClass::protectedStaticFuncOverloaded> {};299template <> class PCT5<&TestClass::privateStaticFunc> : P1 {};300// expected-error@+2 {{implicit instantiation of undefined template}}301// expected-error@+1 {{is a private member of}}302template <> template <> class PCT6<TestClass::PrivateClass>::NPCT1<TestClass::PrivateClass> : PCT6<TestClass::PrivateClass>::NPCT2<int> {};303// expected-error@+1 3{{is a private member of}}304template <> class PCT5<&TestClass::privateStaticFuncOverloaded> : PCT6<TestClass::PrivateClass>::NPCT1<TestClass::PrivateClass> {};305template <> template <typename NT> class PCT6<TestClass::PrivateClass>::NPCT2 : P1 {}; // declaration306 307//----------------------------------------------------------//308 309// template declarations for partial specializations310template <typename T1, typename T2> class CTT1 {};311template <typename T1, typename T2, typename T3> class CTT2 {};312template <typename T, int X> class CTT3 {};313template <typename T, void (TestClass::*)()> class CTT4 {};314template <typename T, void (*)()> class CTT5 {};315template <typename T1, typename T2> class CTT6 {316 template <typename NT> class NCT1 {};317 template <typename NT> class NCT2; // forward declaration318 template <typename NT1, typename NT2> class NCT3 {};319 template <typename NT1, typename NT2> class NCT4; // forward declaration320};321 322// partial specializations323 324// public325template <typename T> class CTT1<T, TestClass::PublicClass> final {};326template <typename T> class CTT1<T, TestClass::TemplatePublicClass<T>> {};327template <typename T> struct CTT1<T, TestClass::TemplatePublicClass<int>> final {};328template <typename T> class CTT1<T, TestClass::AliasPublicClass> {};329template <typename T> struct CTT2<T, TestClass::PublicClass, TestClass::PublicClass> final {};330template <typename T> struct CTT2<TestClass::PublicClass, T, TestClass::PublicClass> {};331template <typename T> class CTT2<TestClass::PublicClass, TestClass::PublicClass, T> final {};332template <typename T> class CTT3<T, TestClass::publicStaticInt> {};333template <typename T> class CTT4<T, &TestClass::publicFunc> final {};334template <typename T> class CTT4<T, &TestClass::publicFuncOverloaded> {};335template <typename T> class CTT5<T, &TestClass::publicStaticFunc> final {};336template <typename T> class CTT5<T, &TestClass::publicStaticFuncOverloaded> {};337template <typename T> class CTT5<T, &globalFunction> final {};338// expected-error@+1 {{cannot specialize a dependent template}}339template <typename T1> template <typename T2> class CTT6<T1, TestClass::PublicClass>::template NCT1<T2 *> {};340template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT1<T3 *> final {};341template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT2 {}; // declaration342template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT2<T3 *> final {};343template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::PublicClass> {};344// expected-error@+1 {{cannot specialize a dependent template}}345template <typename T1> template <typename T2> class CTT6<T1, TestClass::PublicClass>::template NCT3<T2, TestClass::PublicClass> final {};346template <typename T1, typename T2> template <typename T3, typename T4> class CTT6<T1, T2>::NCT4 {}; // declaration347template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::PublicClass> final {};348template <typename T> class CTT6<TestClass::PublicClass, T> {349 template <typename T1, typename T2> class NCT3 {};350 template <typename T1, typename T2> class NCT4;351};352template <typename T1> template <typename T2> class CTT6<TestClass::PublicClass, T1>::NCT3<T2, TestClass::PublicClass> {};353template <typename T1> template <typename, typename> class CTT6<TestClass::PublicClass, T1>::NCT4 final {};354template <typename T1> template <typename T2> class CTT6<TestClass::PublicClass, T1>::NCT4<T2, TestClass::PublicClass> {};355 356// protected357 358template <typename T> class CTT1<T, TestClass::ProtectedClass> {};359template <typename T> class CTT1<T, TestClass::TemplateProtectedClass<T>> final {};360template <typename T> struct CTT1<T, TestClass::TemplateProtectedClass<int>> {};361template <typename T> class CTT1<T, TestClass::AliasProtectedClass> final {};362template <typename T> struct CTT2<T, TestClass::ProtectedClass, TestClass::ProtectedClass> {};363template <typename T> class CTT2<TestClass::ProtectedClass, T, TestClass::ProtectedClass> final {};364template <typename T> struct CTT2<TestClass::ProtectedClass, TestClass::ProtectedClass, T> {};365template <typename T> class CTT3<T, TestClass::protectedStaticInt> final {};366template <typename T> class CTT4<T, &TestClass::protectedFunc> {};367template <typename T> class CTT4<T, &TestClass::protectedFuncOverloaded> final {};368template <typename T> class CTT5<T, &TestClass::protectedStaticFunc> {};369template <typename T> class CTT5<T, &TestClass::protectedStaticFuncOverloaded> final {};370// expected-error@+1 {{cannot specialize a dependent template}}371template <typename T1> template <typename T2> class CTT6<T1, TestClass::ProtectedClass>::template NCT1<T2 *> {};372template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::ProtectedClass> final {};373// expected-error@+1 {{cannot specialize a dependent template}}374template <typename T1> template <typename T2> class CTT6<T1, TestClass::ProtectedClass>::template NCT3<T2, TestClass::ProtectedClass> {};375template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::ProtectedClass> final {};376template <typename T> class CTT6<TestClass::ProtectedClass, T> {377 template <typename T1, typename T2> class NCT3 {};378 template <typename T1, typename T2> class NCT4;379};380template <typename T1> template <typename T2> class CTT6<TestClass::ProtectedClass, T1>::NCT3<T2, TestClass::ProtectedClass> final {};381template <typename T1> template <typename, typename> class CTT6<TestClass::ProtectedClass, T1>::NCT4 {};382template <typename T1> template <typename T2> class CTT6<TestClass::ProtectedClass, T1>::NCT4<T2, TestClass::ProtectedClass> final {};383 384// private385 386template <typename T> class CTT1<T, TestClass::PrivateClass> final {};387template <typename T> class CTT1<T, TestClass::TemplatePrivateClass<T>> {};388template <typename T> struct CTT1<T, TestClass::TemplatePrivateClass<int>> final {};389template <typename T> class CTT1<T, TestClass::AliasPrivateClass> {};390template <typename T> struct CTT2<T, TestClass::PrivateClass, TestClass::PrivateClass> final {};391template <typename T> class CTT2<TestClass::PrivateClass, T, TestClass::PrivateClass> {};392template <typename T> struct CTT2<TestClass::PrivateClass, TestClass::PrivateClass, T> final {};393template <typename T> class CTT3<T, TestClass::privateStaticInt> {};394template <typename T> class CTT4<T, &TestClass::privateFunc> final {};395template <typename T> class CTT4<T, &TestClass::privateFuncOverloaded> {};396template <typename T> class CTT5<T, &TestClass::privateStaticFunc> final {};397template <typename T> class CTT5<T, &TestClass::privateStaticFuncOverloaded> {};398// expected-error@+1 {{cannot specialize a dependent template}}399template <typename T1> template <typename T2> class CTT6<T1, TestClass::PrivateClass>::template NCT1<T2 *> final {};400template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::PrivateClass> {};401// expected-error@+1 {{cannot specialize a dependent template}}402template <typename T1> template <typename T2> class CTT6<T1, TestClass::PrivateClass>::template NCT3<T2, TestClass::PrivateClass> final {};403template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::PrivateClass> {};404template <typename T> class CTT6<TestClass::PrivateClass, T> {405 template <typename T1, typename T2> class NCT3 {};406 template <typename T1, typename T2> class NCT4;407};408template <typename T1> template <typename T2> class CTT6<TestClass::PrivateClass, T1>::NCT3<T2, TestClass::PrivateClass> {};409template <typename T1> template <typename, typename> class CTT6<TestClass::PrivateClass, T1>::NCT4 final {};410template <typename T1> template <typename T2> class CTT6<TestClass::PrivateClass, T1>::NCT4<T2, TestClass::PrivateClass> final {};411 412//----------------------------------------------------------//413 414// template declarations for partial specializations with parents415template <typename T1, typename T2> class PCTT1 {};416template <typename T1, typename T2, typename T3> class PCTT2 {};417template <typename T, int X> class PCTT3 {};418template <typename T, void (TestClass::*)()> class PCTT4 {};419template <typename T, void (*)()> class PCTT5 {};420template <typename T1, typename T2> class PCTT6 {421 template <typename NT> class NCT1 {};422 template <typename NT> class NCT2; // forward declaration423 template <typename NT1, typename NT2> class NCT3 {};424 template <typename NT1, typename NT2> class NCT4; // forward declaration425};426 427// partial specializations with parents428 429// protected + public430template <typename T> class PCTT1<T, TestClass::PublicClass> : P1 {};431template <typename T> struct PCTT1<T, TestClass::TemplatePublicClass<T>> final : PCTT2<T, TestClass::PublicClass, TestClass::PublicClass> {}; // not full but let it be here432template <typename T> class PCTT1<T, TestClass::TemplatePublicClass<int>> : PCTT1<T, TestClass::AliasPublicClass> {};433// expected-error@+1 {{is a protected member of}}434template <typename T> class PCTT1<T, TestClass::TemplatePublicClass<TestClass::TemplateProtectedClass<T>>> final : PCTT1<T, TestClass::ProtectedClass> {};435template <typename T> struct PCTT1<T, TestClass::AliasProtectedClass> : PCTT2<T, TestClass::PublicClass, int> {};436template <typename T> class PCTT2<T, TestClass::ProtectedClass, TestClass::PublicClass> final : PCTT3<T, TestClass::publicStaticInt> {};437template <typename T> class PCTT3<T, TestClass::protectedStaticInt> : PCTT4<T, &TestClass::publicFunc> {};438template <typename T> struct PCTT4<T, &TestClass::protectedFunc> final : PCTT5<T, &TestClass::publicStaticFunc> {};439template <typename T> class PCTT4<T, &TestClass::publicFuncOverloaded> : PCTT5<T, &TestClass::publicStaticFuncOverloaded> {};440template <typename T> class PCTT5<T, &TestClass::protectedStaticFunc> final : PCTT5<T, &TestClass::publicStaticFuncOverloaded> {};441template <typename T> class PCTT5<T, &TestClass::protectedStaticFuncOverloaded> : PCTT6<T, TestClass::PublicClass>::template NCT1<TestClass::PublicClass> {};442// expected-error@+1 {{is a protected member of}}443template <typename T> class PCTT5<T, &globalFunction> : PCTT6<T, TestClass::ProtectedClass>::template NCT1<int> {};444// expected-error@+1 {{is a protected member of}}445template <typename T1, typename T2> template <typename T3> class PCTT6<T1, T2>::NCT2 final : PCTT4<T1, &TestClass::protectedFunc> {}; // declaration446template <typename T1, typename T2> template <typename T3> class PCTT6<T1, T2>::NCT2<T3 *> : P1 {};447// expected-error@+2 {{cannot specialize a dependent template}}448// expected-error@+1 {{is a protected member of}}449template <typename T> template <typename NT> class PCTT6<T, TestClass::ProtectedClass>::template NCT1<NT *> : PCTT6<T, TestClass::ProtectedClass>::template NCT2<int> {};450 451// protected + private452template <typename T> class PCTT1<T, TestClass::PrivateClass> : P1 {};453// expected-error@+2 {{is a protected member of}}454// expected-error@+1 {{is a private member of}}455template <typename T> struct PCTT1<T, TestClass::TemplatePrivateClass<T>> final : PCTT2<T, TestClass::PrivateClass, TestClass::ProtectedClass> {}; // not full but let it be here456// expected-error@+1 {{is a protected member of}}457template <typename T> class PCTT1<T, TestClass::TemplatePrivateClass<int>> : PCTT1<T, TestClass::AliasProtectedClass> {};458// expected-error@+2 {{is a protected member of}}459// expected-error@+1 {{is a private member of}}460template <typename T> struct PCTT1<T, TestClass::AliasPrivateClass> final : PCTT2<T, TestClass::ProtectedClass, TestClass::PrivateClass> {};461// expected-error@+1 {{is a protected member of}}462template <typename T> class PCTT2<T, TestClass::PrivateClass, TestClass::TemplatePrivateClass<T>> : PCTT3<T, TestClass::protectedStaticInt> {};463// expected-error@+1 {{is a protected member of}}464template <typename T> class PCTT3<T, TestClass::privateStaticInt> final : PCTT4<T, &TestClass::protectedFunc> {};465// expected-error@+1 {{is a protected member of}}466template <typename T> struct PCTT4<T, &TestClass::privateFunc> : PCTT5<T, &TestClass::protectedStaticFunc> {};467// expected-error@+1 {{is a protected member of}}468template <typename T> class PCTT4<T, &TestClass::privateFuncOverloaded> final : PCTT5<T, &TestClass::protectedStaticFuncOverloaded> {};469template <typename T> class PCTT5<T, &TestClass::privateStaticFunc> : P1 {};470// expected-error@+2 {{cannot specialize a dependent template}}471// expected-error@+1 {{is a private member of}}472template <typename T> class PCTT6<T, TestClass::PrivateClass>::template PCTT1<TestClass::PrivateClass> : PCTT6<T, TestClass::PrivateClass>::template NCT2<int> {};473// expected-error@+1 {{is a private member of}}474template <typename T> class PCTT5<T, &TestClass::privateStaticFuncOverloaded> final : PCTT6<T, T>::template NCT1<TestClass::PrivateClass> {};475template <typename T> class PCTT6<TestClass::PrivateClass, T> {476 template <typename T1, typename T2> class NCT3 final {};477 template <typename T1, typename T2> class NCT4;478};479template <typename T1> template <typename, typename> class PCTT6<TestClass::PrivateClass, T1>::NCT4 final {};480// expected-error@+1 2{{is a private member of}}481template <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