| // RUN: %clang_cc1 -fsyntax-only -verify %s |
| |
| // C++20 [temp.class.spec] 13.7.5/10 |
| // The usual access checking rules do not apply to non-dependent names |
| // used to specify template arguments of the simple-template-id of the |
| // partial specialization. |
| // |
| // 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... |
| |
| // TODO: add test cases for `enum` |
| |
| // class for tests |
| class TestClass { |
| public: |
| class PublicClass {}; |
| template <class T> class TemplatePublicClass {}; |
| |
| using AliasPublicClass = unsigned char; |
| |
| void publicFunc(); |
| void publicFuncOverloaded(); |
| void publicFuncOverloaded(int); |
| |
| static void publicStaticFunc(); |
| static void publicStaticFuncOverloaded(); |
| static void publicStaticFuncOverloaded(int); |
| |
| static constexpr int publicStaticInt = 42; |
| |
| protected: |
| // expected-note@+1 8{{declared protected here}} |
| class ProtectedClass {}; |
| template <class T> class TemplateProtectedClass {}; |
| |
| // expected-note@+1 2{{declared protected here}} |
| using AliasProtectedClass = const char; |
| |
| // expected-note@+1 3{{declared protected here}} |
| void protectedFunc(); |
| void protectedFuncOverloaded(); |
| void protectedFuncOverloaded(int); |
| |
| // expected-note@+1 2{{declared protected here}} |
| static void protectedStaticFunc(); |
| // expected-note@+1 2{{declared protected here}} |
| static void protectedStaticFuncOverloaded(); |
| static void protectedStaticFuncOverloaded(int); |
| |
| // expected-note@+1 2{{declared protected here}} |
| static constexpr int protectedStaticInt = 43; |
| |
| private: |
| // expected-note@+1 10{{declared private here}} |
| class PrivateClass {}; |
| // expected-note@+1 {{declared private here}} |
| template <class T> class TemplatePrivateClass {}; |
| |
| using AliasPrivateClass = char *; |
| |
| void privateFunc(); |
| void privateFuncOverloaded(); |
| void privateFuncOverloaded(int); |
| |
| static void privateStaticFunc(); |
| static void privateStaticFuncOverloaded(); |
| static void privateStaticFuncOverloaded(int); |
| |
| static constexpr int privateStaticInt = 44; |
| }; |
| |
| void globalFunction() {} |
| |
| //----------------------------------------------------------// |
| |
| // template declarations for explicit instantiations |
| template <typename T> class IT1 {}; |
| template <typename T1, typename T2> class IT2 {}; |
| template <int X> class IT3 {}; |
| template <void (TestClass::*)()> class IT4 {}; |
| template <void (*)()> class IT5 {}; |
| template <typename T> class IT6 { |
| template <typename NT> class NIT1 {}; |
| }; |
| template <typename T1, typename T2> class IT7 {}; |
| template <void (TestClass::*)(), int X> class IT8 {}; |
| template <typename T, void (*)()> class IT9 {}; |
| |
| // explicit instantiations |
| |
| // public |
| template class IT1<TestClass::PublicClass>; |
| template struct IT1<TestClass::TemplatePublicClass<int>>; |
| template class IT1<TestClass::AliasPublicClass>; |
| template struct IT2<TestClass::PublicClass, TestClass::PublicClass>; |
| template class IT3<TestClass::publicStaticInt>; |
| template struct IT4<&TestClass::publicFunc>; |
| template class IT4<&TestClass::publicFuncOverloaded>; |
| template class IT5<&TestClass::publicStaticFunc>; |
| template class IT5<&TestClass::publicStaticFuncOverloaded>; |
| template class IT5<&globalFunction>; |
| template class IT6<TestClass::PublicClass>::template NIT1<TestClass::PublicClass>; |
| template class IT7<TestClass::AliasPublicClass, TestClass::PublicClass>; |
| template struct IT7<TestClass::PublicClass, TestClass::TemplatePublicClass<TestClass::PublicClass>>; |
| template class IT8<&TestClass::publicFunc, TestClass::publicStaticInt>; |
| template class IT8<&TestClass::publicFuncOverloaded, TestClass::publicStaticInt>; |
| template class IT9<TestClass::PublicClass, &TestClass::publicStaticFunc>; |
| template class IT9<TestClass::PublicClass, &TestClass::publicStaticFuncOverloaded>; |
| template class IT9<TestClass::PublicClass, &globalFunction>; |
| |
| // protected |
| template class IT1<TestClass::ProtectedClass>; |
| template struct IT1<TestClass::TemplateProtectedClass<int>>; |
| template class IT1<TestClass::AliasProtectedClass>; |
| template struct IT2<TestClass::ProtectedClass, TestClass::ProtectedClass>; |
| template class IT3<TestClass::protectedStaticInt>; |
| template struct IT4<&TestClass::protectedFunc>; |
| template class IT4<&TestClass::protectedFuncOverloaded>; |
| template class IT5<&TestClass::protectedStaticFunc>; |
| template class IT5<&TestClass::protectedStaticFuncOverloaded>; |
| template class IT6<TestClass::ProtectedClass>::template NIT1<TestClass::ProtectedClass>; |
| template class IT7<TestClass::AliasProtectedClass, TestClass::ProtectedClass>; |
| template struct IT7<TestClass::ProtectedClass, TestClass::TemplateProtectedClass<TestClass::ProtectedClass>>; |
| template class IT8<&TestClass::protectedFunc, TestClass::protectedStaticInt>; |
| template class IT8<&TestClass::protectedFuncOverloaded, TestClass::protectedStaticInt>; |
| template class IT9<TestClass::ProtectedClass, &TestClass::protectedStaticFunc>; |
| template class IT9<TestClass::ProtectedClass, &TestClass::protectedStaticFuncOverloaded>; |
| template class IT9<TestClass::ProtectedClass, &globalFunction>; |
| |
| // private |
| template class IT1<TestClass::PrivateClass>; |
| template struct IT1<TestClass::TemplatePrivateClass<int>>; |
| template class IT1<TestClass::AliasPrivateClass>; |
| template struct IT2<TestClass::PrivateClass, TestClass::PrivateClass>; |
| template class IT3<TestClass::privateStaticInt>; |
| template struct IT4<&TestClass::privateFunc>; |
| template class IT4<&TestClass::privateFuncOverloaded>; |
| template class IT5<&TestClass::privateStaticFunc>; |
| template class IT5<&TestClass::privateStaticFuncOverloaded>; |
| template class IT6<TestClass::PrivateClass>::template NIT1<TestClass::PrivateClass>; |
| template class IT7<TestClass::AliasPrivateClass, TestClass::PrivateClass>; |
| template struct IT7<TestClass::PrivateClass, TestClass::TemplatePrivateClass<TestClass::PrivateClass>>; |
| template class IT8<&TestClass::privateFunc, TestClass::privateStaticInt>; |
| template class IT8<&TestClass::privateFuncOverloaded, TestClass::privateStaticInt>; |
| template class IT9<TestClass::PrivateClass, &TestClass::privateStaticFunc>; |
| template class IT9<TestClass::PrivateClass, &TestClass::privateStaticFuncOverloaded>; |
| template class IT9<TestClass::PrivateClass, &globalFunction>; |
| |
| //----------------------------------------------------------// |
| |
| // template declarations for full specializations |
| template <typename T> class CT1 {}; |
| template <typename T1, typename T2> class CT2 {}; |
| template <int X> class CT3 {}; |
| template <void (TestClass::*)()> class CT4 {}; |
| template <void (*)()> class CT5 {}; |
| template <typename T> class CT6 { |
| template <typename NT> class NCT1 {}; |
| template <typename NT> class NCT2; // forward declaration |
| }; |
| |
| // full specializations |
| |
| // public |
| template <> class CT1<TestClass::PublicClass>; |
| template <typename T> class CT1<TestClass::TemplatePublicClass<T>>; // not full but let it be here |
| template <> struct CT1<TestClass::TemplatePublicClass<int>>; |
| template <> class CT1<TestClass::AliasPublicClass>; |
| template <> struct CT2<TestClass::PublicClass, TestClass::PublicClass>; |
| template <> class CT3<TestClass::publicStaticInt>; |
| template <> struct CT4<&TestClass::publicFunc>; |
| template <> class CT4<&TestClass::publicFuncOverloaded>; |
| template <> struct CT5<&TestClass::publicStaticFunc>; |
| template <> class CT5<&TestClass::publicStaticFuncOverloaded>; |
| template <> class CT5<&globalFunction>; |
| template <> template <> class CT6<TestClass::PublicClass>::NCT1<TestClass::PublicClass>; |
| |
| template <> class CT1<TestClass::PublicClass> final {}; |
| template <typename T> class CT1<TestClass::TemplatePublicClass<T>> {}; |
| template <> class CT1<TestClass::TemplatePublicClass<int>> final {}; |
| template <> class CT1<TestClass::AliasPublicClass> {}; |
| template <> class CT2<TestClass::PublicClass, TestClass::PublicClass> final {}; |
| template <> class CT3<TestClass::publicStaticInt> {}; |
| template <> class CT4<&TestClass::publicFunc> final {}; |
| template <> class CT4<&TestClass::publicFuncOverloaded> {}; |
| template <> class CT5<&TestClass::publicStaticFunc> final {}; |
| template <> class CT5<&TestClass::publicStaticFuncOverloaded> {}; |
| template <> class CT5<&globalFunction> final {}; |
| template <> template <> class CT6<TestClass::PublicClass>::NCT1<TestClass::PublicClass> {}; |
| template <> template <typename NT> class CT6<TestClass::PublicClass>::NCT2 final {}; // declaration |
| |
| // protected |
| template <> class CT1<TestClass::ProtectedClass>; |
| template <typename T> class CT1<TestClass::TemplateProtectedClass<T>>; // not full but let it be here |
| template <> class CT1<TestClass::TemplateProtectedClass<int>>; |
| template <> struct CT1<TestClass::AliasProtectedClass>; |
| template <> class CT2<TestClass::ProtectedClass, TestClass::ProtectedClass>; |
| template <> struct CT3<TestClass::protectedStaticInt>; |
| template <> class CT4<&TestClass::protectedFunc>; |
| template <> struct CT4<&TestClass::protectedFuncOverloaded>; |
| template <> class CT5<&TestClass::protectedStaticFunc>; |
| template <> class CT5<&TestClass::protectedStaticFuncOverloaded>; |
| template <> template <> class CT6<TestClass::ProtectedClass>::NCT1<TestClass::ProtectedClass>; |
| |
| template <> class CT1<TestClass::ProtectedClass> {}; |
| template <typename T> class CT1<TestClass::TemplateProtectedClass<T>> final {}; // not full but let it be here |
| template <> class CT1<TestClass::TemplateProtectedClass<int>> {}; |
| template <> class CT1<TestClass::AliasProtectedClass> final {}; |
| template <> class CT2<TestClass::ProtectedClass, TestClass::ProtectedClass> {}; |
| template <> class CT3<TestClass::protectedStaticInt> final {}; |
| template <> class CT4<&TestClass::protectedFunc> {}; |
| template <> class CT4<&TestClass::protectedFuncOverloaded> final {}; |
| template <> class CT5<&TestClass::protectedStaticFunc> {}; |
| template <> class CT5<&TestClass::protectedStaticFuncOverloaded> final {}; |
| template <> template <> class CT6<TestClass::ProtectedClass>::NCT1<TestClass::ProtectedClass> {}; |
| template <> template <typename NT> class CT6<TestClass::ProtectedClass>::NCT2 final {}; // declaration |
| |
| // private |
| template <> class CT1<TestClass::PrivateClass>; |
| template <typename T> class CT1<TestClass::TemplatePrivateClass<T>>; // not full but let it be here |
| template <> struct CT1<TestClass::TemplatePrivateClass<int>>; |
| template <> class CT1<TestClass::AliasPrivateClass>; |
| template <> struct CT2<TestClass::PrivateClass, TestClass::PrivateClass>; |
| template <> class CT3<TestClass::privateStaticInt>; |
| template <> struct CT4<&TestClass::privateFunc>; |
| template <> class CT4<&TestClass::privateFuncOverloaded>; |
| template <> class CT5<&TestClass::privateStaticFunc>; |
| template <> class CT5<&TestClass::privateStaticFuncOverloaded>; |
| template <> template <> class CT6<TestClass::PrivateClass>::NCT1<TestClass::PrivateClass>; |
| |
| template <> class CT1<TestClass::PrivateClass> final {}; |
| template <typename T> class CT1<TestClass::TemplatePrivateClass<T>> {}; // not full but let it be here |
| template <> class CT1<TestClass::TemplatePrivateClass<int>> final {}; |
| template <> class CT1<TestClass::AliasPrivateClass> {}; |
| template <> class CT2<TestClass::PrivateClass, TestClass::PrivateClass> final {}; |
| template <> class CT3<TestClass::privateStaticInt> {}; |
| template <> class CT4<&TestClass::privateFunc> final {}; // PR37424 |
| template <> class CT4<&TestClass::privateFuncOverloaded> {}; // PR37424 |
| template <> class CT5<&TestClass::privateStaticFunc> final {}; |
| template <> class CT5<&TestClass::privateStaticFuncOverloaded> {}; |
| template <> template <> class CT6<TestClass::PrivateClass>::NCT1<TestClass::PrivateClass> final {}; |
| template <> template <typename NT> class CT6<TestClass::PrivateClass>::NCT2 {}; // declaration |
| |
| //----------------------------------------------------------// |
| |
| // template declarations for full specializations with parents |
| class P1 {}; |
| template <typename T> class PCT1 {}; |
| template <typename T1, typename T2> class PCT2 {}; |
| template <int X> class PCT3 {}; |
| template <void (TestClass::*)()> class PCT4 {}; |
| template <void (*)()> class PCT5 {}; |
| template <typename T> class PCT6 { |
| // expected-note@+1 3{{implicitly declared private here}} |
| template <typename NT> class NPCT1 {}; |
| // expected-note@+1 {{template is declared here}} |
| template <typename NT> class NPCT2; // forward declaration |
| }; |
| |
| // full specializations with parents |
| |
| // protected + public |
| template <> class PCT1<TestClass::PublicClass> : P1 {}; |
| template <typename T> class PCT1<TestClass::TemplatePublicClass<T>> : PCT2<TestClass::PublicClass, TestClass::PublicClass> {}; // not full but let it be here |
| template <> struct PCT1<TestClass::TemplatePublicClass<int>> : PCT1<TestClass::AliasPublicClass> {}; |
| template <> class PCT1<TestClass::AliasProtectedClass> : PCT2<TestClass::PublicClass, int> {}; |
| template <> struct PCT2<TestClass::ProtectedClass, TestClass::PublicClass> : PCT3<TestClass::publicStaticInt> {}; |
| template <> class PCT3<TestClass::protectedStaticInt> : PCT4<&TestClass::publicFunc> {}; |
| template <> struct PCT4<&TestClass::protectedFunc> : PCT5<&TestClass::publicStaticFunc> {}; |
| template <> class PCT4<&TestClass::publicFuncOverloaded> : PCT5<&TestClass::publicStaticFuncOverloaded> {}; |
| template <> class PCT5<&TestClass::protectedStaticFunc> : PCT5<&TestClass::publicStaticFuncOverloaded> {}; |
| // expected-error@+1 {{is a private member of}} |
| template <> class PCT5<&TestClass::protectedStaticFuncOverloaded> : PCT6<TestClass::PublicClass>::NPCT1<TestClass::PublicClass> {}; |
| // expected-error@+2 {{is a protected member of}} |
| // expected-error@+1 {{is a private member of}} |
| template <> class PCT5<&globalFunction> : PCT6<TestClass::ProtectedClass>::NPCT1<int> {}; |
| template <> template <typename NT> class PCT6<TestClass::PublicClass>::NPCT2 : P1 {}; // declaration |
| template <> template <> class PCT6<TestClass::PublicClass>::NPCT1<TestClass::ProtectedClass> : PCT6<TestClass::PublicClass>::template NPCT2<int> {}; |
| |
| // protected + private |
| template <> class PCT1<TestClass::PrivateClass> : P1 {}; |
| // expected-error@+2 {{is a protected member of}} |
| // expected-error@+1 {{is a private member of}} |
| template <typename T> class PCT1<TestClass::TemplatePrivateClass<T>> : PCT2<TestClass::PrivateClass, TestClass::ProtectedClass> {}; // not full but let it be here |
| // expected-error@+1 {{is a protected member of}} |
| template <> class PCT1<TestClass::TemplatePrivateClass<int>> : PCT1<TestClass::AliasProtectedClass> {}; |
| // expected-error@+2 {{is a protected member of}} |
| // expected-error@+1 {{is a private member of}} |
| template <> class PCT1<TestClass::AliasPrivateClass> : PCT2<TestClass::ProtectedClass, TestClass::PrivateClass> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <> class PCT2<TestClass::PrivateClass, TestClass::PrivateClass> : PCT3<TestClass::protectedStaticInt> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <> class PCT3<TestClass::privateStaticInt> : PCT4<&TestClass::protectedFunc> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <> class PCT4<&TestClass::privateFunc> : PCT5<&TestClass::protectedStaticFunc> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <> class PCT4<&TestClass::privateFuncOverloaded> : PCT5<&TestClass::protectedStaticFuncOverloaded> {}; |
| template <> class PCT5<&TestClass::privateStaticFunc> : P1 {}; |
| // expected-error@+2 {{implicit instantiation of undefined template}} |
| // expected-error@+1 {{is a private member of}} |
| template <> template <> class PCT6<TestClass::PrivateClass>::NPCT1<TestClass::PrivateClass> : PCT6<TestClass::PrivateClass>::NPCT2<int> {}; |
| // expected-error@+1 3{{is a private member of}} |
| template <> class PCT5<&TestClass::privateStaticFuncOverloaded> : PCT6<TestClass::PrivateClass>::NPCT1<TestClass::PrivateClass> {}; |
| template <> template <typename NT> class PCT6<TestClass::PrivateClass>::NPCT2 : P1 {}; // declaration |
| |
| //----------------------------------------------------------// |
| |
| // template declarations for partial specializations |
| template <typename T1, typename T2> class CTT1 {}; |
| template <typename T1, typename T2, typename T3> class CTT2 {}; |
| template <typename T, int X> class CTT3 {}; |
| template <typename T, void (TestClass::*)()> class CTT4 {}; |
| template <typename T, void (*)()> class CTT5 {}; |
| template <typename T1, typename T2> class CTT6 { |
| template <typename NT> class NCT1 {}; |
| template <typename NT> class NCT2; // forward declaration |
| template <typename NT1, typename NT2> class NCT3 {}; |
| template <typename NT1, typename NT2> class NCT4; // forward declaration |
| }; |
| |
| // partial specializations |
| |
| // public |
| template <typename T> class CTT1<T, TestClass::PublicClass> final {}; |
| template <typename T> class CTT1<T, TestClass::TemplatePublicClass<T>> {}; |
| template <typename T> struct CTT1<T, TestClass::TemplatePublicClass<int>> final {}; |
| template <typename T> class CTT1<T, TestClass::AliasPublicClass> {}; |
| template <typename T> struct CTT2<T, TestClass::PublicClass, TestClass::PublicClass> final {}; |
| template <typename T> struct CTT2<TestClass::PublicClass, T, TestClass::PublicClass> {}; |
| template <typename T> class CTT2<TestClass::PublicClass, TestClass::PublicClass, T> final {}; |
| template <typename T> class CTT3<T, TestClass::publicStaticInt> {}; |
| template <typename T> class CTT4<T, &TestClass::publicFunc> final {}; |
| template <typename T> class CTT4<T, &TestClass::publicFuncOverloaded> {}; |
| template <typename T> class CTT5<T, &TestClass::publicStaticFunc> final {}; |
| template <typename T> class CTT5<T, &TestClass::publicStaticFuncOverloaded> {}; |
| template <typename T> class CTT5<T, &globalFunction> final {}; |
| // expected-error@+1 {{cannot specialize a dependent template}} |
| template <typename T1> template <typename T2> class CTT6<T1, TestClass::PublicClass>::template NCT1<T2 *> {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT1<T3 *> final {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT2 {}; // declaration |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT2<T3 *> final {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::PublicClass> {}; |
| // expected-error@+1 {{cannot specialize a dependent template}} |
| template <typename T1> template <typename T2> class CTT6<T1, TestClass::PublicClass>::template NCT3<T2, TestClass::PublicClass> final {}; |
| template <typename T1, typename T2> template <typename T3, typename T4> class CTT6<T1, T2>::NCT4 {}; // declaration |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::PublicClass> final {}; |
| template <typename T> class CTT6<TestClass::PublicClass, T> { |
| template <typename T1, typename T2> class NCT3 {}; |
| template <typename T1, typename T2> class NCT4; |
| }; |
| template <typename T1> template <typename T2> class CTT6<TestClass::PublicClass, T1>::NCT3<T2, TestClass::PublicClass> {}; |
| template <typename T1> template <typename, typename> class CTT6<TestClass::PublicClass, T1>::NCT4 final {}; |
| template <typename T1> template <typename T2> class CTT6<TestClass::PublicClass, T1>::NCT4<T2, TestClass::PublicClass> {}; |
| |
| // protected |
| |
| template <typename T> class CTT1<T, TestClass::ProtectedClass> {}; |
| template <typename T> class CTT1<T, TestClass::TemplateProtectedClass<T>> final {}; |
| template <typename T> struct CTT1<T, TestClass::TemplateProtectedClass<int>> {}; |
| template <typename T> class CTT1<T, TestClass::AliasProtectedClass> final {}; |
| template <typename T> struct CTT2<T, TestClass::ProtectedClass, TestClass::ProtectedClass> {}; |
| template <typename T> class CTT2<TestClass::ProtectedClass, T, TestClass::ProtectedClass> final {}; |
| template <typename T> struct CTT2<TestClass::ProtectedClass, TestClass::ProtectedClass, T> {}; |
| template <typename T> class CTT3<T, TestClass::protectedStaticInt> final {}; |
| template <typename T> class CTT4<T, &TestClass::protectedFunc> {}; |
| template <typename T> class CTT4<T, &TestClass::protectedFuncOverloaded> final {}; |
| template <typename T> class CTT5<T, &TestClass::protectedStaticFunc> {}; |
| template <typename T> class CTT5<T, &TestClass::protectedStaticFuncOverloaded> final {}; |
| // expected-error@+1 {{cannot specialize a dependent template}} |
| template <typename T1> template <typename T2> class CTT6<T1, TestClass::ProtectedClass>::template NCT1<T2 *> {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::ProtectedClass> final {}; |
| // expected-error@+1 {{cannot specialize a dependent template}} |
| template <typename T1> template <typename T2> class CTT6<T1, TestClass::ProtectedClass>::template NCT3<T2, TestClass::ProtectedClass> {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::ProtectedClass> final {}; |
| template <typename T> class CTT6<TestClass::ProtectedClass, T> { |
| template <typename T1, typename T2> class NCT3 {}; |
| template <typename T1, typename T2> class NCT4; |
| }; |
| template <typename T1> template <typename T2> class CTT6<TestClass::ProtectedClass, T1>::NCT3<T2, TestClass::ProtectedClass> final {}; |
| template <typename T1> template <typename, typename> class CTT6<TestClass::ProtectedClass, T1>::NCT4 {}; |
| template <typename T1> template <typename T2> class CTT6<TestClass::ProtectedClass, T1>::NCT4<T2, TestClass::ProtectedClass> final {}; |
| |
| // private |
| |
| template <typename T> class CTT1<T, TestClass::PrivateClass> final {}; |
| template <typename T> class CTT1<T, TestClass::TemplatePrivateClass<T>> {}; |
| template <typename T> struct CTT1<T, TestClass::TemplatePrivateClass<int>> final {}; |
| template <typename T> class CTT1<T, TestClass::AliasPrivateClass> {}; |
| template <typename T> struct CTT2<T, TestClass::PrivateClass, TestClass::PrivateClass> final {}; |
| template <typename T> class CTT2<TestClass::PrivateClass, T, TestClass::PrivateClass> {}; |
| template <typename T> struct CTT2<TestClass::PrivateClass, TestClass::PrivateClass, T> final {}; |
| template <typename T> class CTT3<T, TestClass::privateStaticInt> {}; |
| template <typename T> class CTT4<T, &TestClass::privateFunc> final {}; |
| template <typename T> class CTT4<T, &TestClass::privateFuncOverloaded> {}; |
| template <typename T> class CTT5<T, &TestClass::privateStaticFunc> final {}; |
| template <typename T> class CTT5<T, &TestClass::privateStaticFuncOverloaded> {}; |
| // expected-error@+1 {{cannot specialize a dependent template}} |
| template <typename T1> template <typename T2> class CTT6<T1, TestClass::PrivateClass>::template NCT1<T2 *> final {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT3<T3, TestClass::PrivateClass> {}; |
| // expected-error@+1 {{cannot specialize a dependent template}} |
| template <typename T1> template <typename T2> class CTT6<T1, TestClass::PrivateClass>::template NCT3<T2, TestClass::PrivateClass> final {}; |
| template <typename T1, typename T2> template <typename T3> class CTT6<T1, T2>::NCT4<T3, TestClass::PrivateClass> {}; |
| template <typename T> class CTT6<TestClass::PrivateClass, T> { |
| template <typename T1, typename T2> class NCT3 {}; |
| template <typename T1, typename T2> class NCT4; |
| }; |
| template <typename T1> template <typename T2> class CTT6<TestClass::PrivateClass, T1>::NCT3<T2, TestClass::PrivateClass> {}; |
| template <typename T1> template <typename, typename> class CTT6<TestClass::PrivateClass, T1>::NCT4 final {}; |
| template <typename T1> template <typename T2> class CTT6<TestClass::PrivateClass, T1>::NCT4<T2, TestClass::PrivateClass> final {}; |
| |
| //----------------------------------------------------------// |
| |
| // template declarations for partial specializations with parents |
| template <typename T1, typename T2> class PCTT1 {}; |
| template <typename T1, typename T2, typename T3> class PCTT2 {}; |
| template <typename T, int X> class PCTT3 {}; |
| template <typename T, void (TestClass::*)()> class PCTT4 {}; |
| template <typename T, void (*)()> class PCTT5 {}; |
| template <typename T1, typename T2> class PCTT6 { |
| template <typename NT> class NCT1 {}; |
| template <typename NT> class NCT2; // forward declaration |
| template <typename NT1, typename NT2> class NCT3 {}; |
| template <typename NT1, typename NT2> class NCT4; // forward declaration |
| }; |
| |
| // partial specializations with parents |
| |
| // protected + public |
| template <typename T> class PCTT1<T, TestClass::PublicClass> : P1 {}; |
| template <typename T> struct PCTT1<T, TestClass::TemplatePublicClass<T>> final : PCTT2<T, TestClass::PublicClass, TestClass::PublicClass> {}; // not full but let it be here |
| template <typename T> class PCTT1<T, TestClass::TemplatePublicClass<int>> : PCTT1<T, TestClass::AliasPublicClass> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> class PCTT1<T, TestClass::TemplatePublicClass<TestClass::TemplateProtectedClass<T>>> final : PCTT1<T, TestClass::ProtectedClass> {}; |
| template <typename T> struct PCTT1<T, TestClass::AliasProtectedClass> : PCTT2<T, TestClass::PublicClass, int> {}; |
| template <typename T> class PCTT2<T, TestClass::ProtectedClass, TestClass::PublicClass> final : PCTT3<T, TestClass::publicStaticInt> {}; |
| template <typename T> class PCTT3<T, TestClass::protectedStaticInt> : PCTT4<T, &TestClass::publicFunc> {}; |
| template <typename T> struct PCTT4<T, &TestClass::protectedFunc> final : PCTT5<T, &TestClass::publicStaticFunc> {}; |
| template <typename T> class PCTT4<T, &TestClass::publicFuncOverloaded> : PCTT5<T, &TestClass::publicStaticFuncOverloaded> {}; |
| template <typename T> class PCTT5<T, &TestClass::protectedStaticFunc> final : PCTT5<T, &TestClass::publicStaticFuncOverloaded> {}; |
| template <typename T> class PCTT5<T, &TestClass::protectedStaticFuncOverloaded> : PCTT6<T, TestClass::PublicClass>::template NCT1<TestClass::PublicClass> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> class PCTT5<T, &globalFunction> : PCTT6<T, TestClass::ProtectedClass>::template NCT1<int> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T1, typename T2> template <typename T3> class PCTT6<T1, T2>::NCT2 final : PCTT4<T1, &TestClass::protectedFunc> {}; // declaration |
| template <typename T1, typename T2> template <typename T3> class PCTT6<T1, T2>::NCT2<T3 *> : P1 {}; |
| // expected-error@+2 {{cannot specialize a dependent template}} |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> template <typename NT> class PCTT6<T, TestClass::ProtectedClass>::template NCT1<NT *> : PCTT6<T, TestClass::ProtectedClass>::template NCT2<int> {}; |
| |
| // protected + private |
| template <typename T> class PCTT1<T, TestClass::PrivateClass> : P1 {}; |
| // expected-error@+2 {{is a protected member of}} |
| // expected-error@+1 {{is a private member of}} |
| template <typename T> struct PCTT1<T, TestClass::TemplatePrivateClass<T>> final : PCTT2<T, TestClass::PrivateClass, TestClass::ProtectedClass> {}; // not full but let it be here |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> class PCTT1<T, TestClass::TemplatePrivateClass<int>> : PCTT1<T, TestClass::AliasProtectedClass> {}; |
| // expected-error@+2 {{is a protected member of}} |
| // expected-error@+1 {{is a private member of}} |
| template <typename T> struct PCTT1<T, TestClass::AliasPrivateClass> final : PCTT2<T, TestClass::ProtectedClass, TestClass::PrivateClass> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> class PCTT2<T, TestClass::PrivateClass, TestClass::TemplatePrivateClass<T>> : PCTT3<T, TestClass::protectedStaticInt> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> class PCTT3<T, TestClass::privateStaticInt> final : PCTT4<T, &TestClass::protectedFunc> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> struct PCTT4<T, &TestClass::privateFunc> : PCTT5<T, &TestClass::protectedStaticFunc> {}; |
| // expected-error@+1 {{is a protected member of}} |
| template <typename T> class PCTT4<T, &TestClass::privateFuncOverloaded> final : PCTT5<T, &TestClass::protectedStaticFuncOverloaded> {}; |
| template <typename T> class PCTT5<T, &TestClass::privateStaticFunc> : P1 {}; |
| // expected-error@+2 {{cannot specialize a dependent template}} |
| // expected-error@+1 {{is a private member of}} |
| template <typename T> class PCTT6<T, TestClass::PrivateClass>::template PCTT1<TestClass::PrivateClass> : PCTT6<T, TestClass::PrivateClass>::template NCT2<int> {}; |
| // expected-error@+1 {{is a private member of}} |
| template <typename T> class PCTT5<T, &TestClass::privateStaticFuncOverloaded> final : PCTT6<T, T>::template NCT1<TestClass::PrivateClass> {}; |
| template <typename T> class PCTT6<TestClass::PrivateClass, T> { |
| template <typename T1, typename T2> class NCT3 final {}; |
| template <typename T1, typename T2> class NCT4; |
| }; |
| template <typename T1> template <typename, typename> class PCTT6<TestClass::PrivateClass, T1>::NCT4 final {}; |
| // expected-error@+1 2{{is a private member of}} |
| template <typename T1> template <typename T2> struct PCTT6<TestClass::PrivateClass, T1>::template NCT3<T2, TestClass::TemplatePrivateClass<TestClass::TemplateProtectedClass<TestClass::PublicClass>>> : PCTT6<TestClass::PrivateClass, T1>::NCT4<T2, TestClass::TemplatePrivateClass<int>> {}; |