1 // RUN: %clang_cc1 -verify %s -std=c++11
3 template<typename T
> struct A
{
4 template<typename U
> struct B
;
5 template<typename U
> using C
= U
; // expected-note {{here}}
9 template<typename T
> X(T
);
11 template<typename T
> Y(T
);
15 template<typename T
> A
// expected-warning {{missing 'typename'}}
17 template<typename T
> A
<T
>::C
<T
> f2(); // expected-warning {{missing 'typename'}}
19 // FIXME: Should these cases really be valid? There doesn't appear to be a rule prohibiting them...
20 template<typename T
> A
<T
>::C
<X
>::X(T
) {}
21 template<typename T
> A
<T
>::C
<X
>::X::Y::Y(T
) {}
23 // FIXME: This is ill-formed
24 template<typename T
> int A
<T
>::B
<T
>::*f3() {}
25 template<typename T
> int A
<T
>::C
<X
>::*f4() {}
27 // FIXME: This is valid
28 template<typename T
> int A
<T
>::template C
<int>::*f5() {} // expected-error {{has no members}}
30 template<typename T
> template<typename U
> struct A
<T
>::B
{
31 friend A
<T
>::C
<T
> f6(); // ok, same as 'friend T f6();'
33 friend A
<U
>::C
<T
> f7(); // expected-error {{use 'template' keyword to treat 'C' as a dependent template name}} expected-warning {{missing 'typename'}}
34 friend A
<U
>::template C
<T
> f8(); // expected-warning {{missing 'typename'}}