// RUN: %clang_cc1 -fsyntax-only -pedantic-errors -verify %s template struct A { template struct B { // FIXME: The standard does not seem to consider non-friend elaborated-type-specifiers that // declare partial specializations/explicit specializations/explicit instantiations to be // declarative, see https://lists.isocpp.org/core/2024/01/15325.php struct C; template struct D; void f(); template void g(); static int x; template static int y; enum class E; }; }; template template struct A::template B::C { }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> struct A::template B::C; // expected-error{{'template' cannot be used after a declarative}} template<> template<> struct A::template B::C { }; // expected-error{{'template' cannot be used after a declarative}} template template template struct A::template B::D; // expected-error{{'template' cannot be used after a declarative}} template template template struct A::B::template D; // expected-error{{'template' cannot be used after a declarative}} template template template struct A::template B::D { }; // expected-error{{'template' cannot be used after a declarative}} template template template struct A::template B::D { }; // expected-error{{'template' cannot be used after a declarative}} template template template struct A::B::template D { }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template struct A::template B::D; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> struct A::template B::D; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> struct A::B::template D; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template struct A::template B::D; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template struct A::B::template D; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template struct A::template B::D { }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> struct A::template B::D { }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> struct A::B::template D { }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template struct A::template B::D { }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template struct A::B::template D { }; // expected-error{{'template' cannot be used after a declarative}} template template void A::template B::f() { } // expected-error{{'template' cannot be used after a declarative}} template<> template<> void A::template B::f() { } // expected-error{{'template' cannot be used after a declarative}} template template template void A::template B::g() { } // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> void A::B::template g() { } // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> void A::template B::g() { } // expected-error{{'template' cannot be used after a declarative}} template<> template<> template void A::template B::g() { } // expected-error{{'template' cannot be used after a declarative}} template template int A::template B::x = 0; // expected-error{{'template' cannot be used after a declarative}} template template template int A::template B::y = 0; // expected-error{{'template' cannot be used after a declarative}} template template template int A::template B::y = 0; // expected-error{{'template' cannot be used after a declarative}} template template template int A::B::template y = 0; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template int A::template B::y = 0; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> int A::template B::y = 0; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template<> int A::B::template y = 0; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template int A::template B::y = 0; // expected-error{{'template' cannot be used after a declarative}} template<> template<> template int A::B::template y = 0; // expected-error{{'template' cannot be used after a declarative}} template template enum class A::template B::E { a }; // expected-error{{'template' cannot be used after a declarative}} template<> template<> enum class A::template B::E; // expected-error{{'template' cannot be used after a declarative}} template<> template<> enum class A::template B::E { a }; // expected-error{{'template' cannot be used after a declarative}} // FIXME: We don't call Sema::diagnoseQualifiedDeclaration for friend declarations right now template struct F { // FIXME: f should be assumed to name a template per [temp.names] p3.4 friend void T::f(); // expected-error@-1{{use 'template' keyword to treat 'f' as a dependent template name}} // expected-error@-2{{no candidate function template was found for}} // FIXME: We should diagnose the presence of 'template' here friend void T::template f(); // expected-error{{no candidate function template was found for}} friend void T::template U::f(); // These should be allowed friend class T::template U; friend class T::template U::V; };