// RUN: %clang_cc1 -fsyntax-only -verify %s class A; class S { public: template<typename T> struct A { struct Nested { typedef T type; }; }; }; int i; S::A<int>::Nested::type *ip = &i; template<typename T> struct Outer { template<typename U> class Inner0; template<typename U> class Inner1 { struct ReallyInner; T foo(U); template<typename V> T bar(V); template<typename V> T* bar(V); static T value1; static U value2; }; }; template<typename X> template<typename Y> class Outer<X>::Inner0 { public: void f(X, Y); }; template<typename X> template<typename Y> void Outer<X>::Inner0<Y>::f(X, Y) { } template<typename X> template<typename Y> struct Outer<X>::Inner1<Y>::ReallyInner { static Y value3; void g(X, Y); }; template<typename X> template<typename Y> void Outer<X>::Inner1<Y>::ReallyInner::g(X, Y) { } template<typename X> template<typename Y> X Outer<X>::Inner1<Y>::foo(Y) { return X(); } template<typename X> template<typename Y> template<typename Z> X Outer<X>::Inner1<Y>::bar(Z) { return X(); } template<typename X> template<typename Y> template<typename Z> X* Outer<X>::Inner1<Y>::bar(Z) { return 0; } template<typename X> template<typename Y> X Outer<X>::Inner1<Y>::value1 = 0; template<typename X> template<typename Y> Y Outer<X>::Inner1<Y>::value2 = Y(); template<typename X> template<typename Y> Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y(); template<typename X> template<typename Y> Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}} template<typename T> struct X0 { }; template<typename T> struct X0<T*> { template<typename U> void f(U u = T()) { } }; // PR5103 template<typename> struct X1 { template<typename, bool = false> struct B { }; }; template struct X1<int>::B<bool>; // Template template parameters template<typename T> struct X2 { template<template<class U, T Value> class> // expected-error{{cannot have type 'float'}} \ // expected-note{{previous non-type template}} struct Inner { }; }; template<typename T, int Value> // expected-note{{template non-type parameter}} struct X2_arg; X2<int>::Inner<X2_arg> x2i1; X2<float> x2a; // expected-note{{instantiation}} X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}} namespace PR10896 { template<typename TN> class Foo { public: void foo() {} private: template<typename T> T SomeField; // expected-error {{member 'SomeField' declared as a template}} template<> int SomeField2; // expected-error {{extraneous 'template<>' in declaration of member 'SomeField2'}} }; void g() { Foo<int> f; f.foo(); } } namespace PR10924 { template< class Topology, class ctype > struct ReferenceElement { }; template< class Topology, class ctype > template< int codim > class ReferenceElement< Topology, ctype > :: BaryCenterArray // expected-error{{out-of-line definition of 'BaryCenterArray' does not match any declaration in 'ReferenceElement<Topology, ctype>'}} { }; } class Outer1 { template <typename T> struct X; template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}} };