34 lines · cpp
1// RUN: %clang_cc1 -verify %s -std=c++112 3template<typename T> struct A {4 template<typename U> struct B;5 template<typename U> using C = U;6};7 8struct X {9 template<typename T> X(T);10 struct Y {11 template<typename T> Y(T);12 };13};14 15template<typename T> A // expected-warning {{missing 'typename'}}16 <T>::B<T> f1();17template<typename T> A<T>::C<T> f2(); // expected-warning {{missing 'typename'}}18 19// FIXME: Should these cases really be valid? There doesn't appear to be a rule prohibiting them...20template<typename T> A<T>::C<X>::X(T) {}21template<typename T> A<T>::C<X>::X::Y::Y(T) {}22 23template<typename T> int A<T>::B<T>::*f3() {} // expected-error {{expected unqualified-id}}24template<typename T> int A<T>::C<X>::*f4() {} // expected-error {{expected unqualified-id}}25 26template<typename T> int A<T>::template C<int>::*f5() {}27 28template<typename T> template<typename U> struct A<T>::B {29 friend A<T>::C<T> f6(); // ok, same as 'friend T f6();'30 31 friend A<U>::C<T> f7(); // expected-error {{use 'template' keyword to treat 'C' as a dependent template name}} expected-warning {{missing 'typename'}}32 friend A<U>::template C<T> f8(); // expected-warning {{missing 'typename'}}33};34