template-id-expr.cpp revision 9d9922af13edf3ddf8804a41a98d997324fdd58e
1// RUN: %clang_cc1 -fsyntax-only -verify %s 2// PR5336 3template<typename FromCl> 4struct isa_impl_cl { 5 template<class ToCl> 6 static void isa(const FromCl &Val) { } 7}; 8 9template<class X, class Y> 10void isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); } 11 12class Value; 13void f0(const Value &Val) { isa<Value>(Val); } 14 15// Implicit template-ids. 16template<typename T> 17struct X0 { 18 template<typename U> 19 void f1(); 20 21 template<typename U> 22 void f2(U) { 23 f1<U>(); 24 } 25}; 26 27void test_X0_int(X0<int> xi, float f) { 28 xi.f2(f); 29} 30 31// Not template-id expressions, but they almost look like it. 32template<typename F> 33struct Y { 34 Y(const F&); 35}; 36 37template<int I> 38struct X { 39 X(int, int); 40 void f() { 41 Y<X<I> >(X<I>(0, 0)); 42 Y<X<I> >(::X<I>(0, 0)); 43 } 44}; 45 46template struct X<3>; 47 48// 'template' as a disambiguator. 49// PR7030 50struct Y0 { 51 template<typename U> 52 void f1(U); 53 54 template<typename U> 55 static void f2(U); 56 57 void f3(int); 58 59 static int f4(int); 60 template<typename U> 61 static void f4(U); 62 63 template<typename U> 64 void f() { 65 Y0::template f1<U>(0); 66 Y0::template f1(0); 67 this->template f1(0); 68 69 Y0::template f2<U>(0); 70 Y0::template f2(0); 71 72 Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} 73 Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} 74 75 int x; 76 x = Y0::f4(0); 77 x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 78 x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 79 80 x = this->f4(0); 81 x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 82 x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 83 } 84}; 85 86struct A { 87 template<int I> 88 struct B { 89 static void b1(); 90 }; 91}; 92 93template<int I> 94void f5() { 95 A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}} 96} 97 98template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} 99