1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 // PR5336 3 template<typename FromCl> 4 struct isa_impl_cl { 5 template<class ToCl> 6 static void isa(const FromCl &Val) { } 7 }; 8 9 template<class X, class Y> 10 void isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); } 11 12 class Value; 13 void f0(const Value &Val) { isa<Value>(Val); } 14 15 // Implicit template-ids. 16 template<typename T> 17 struct X0 { 18 template<typename U> 19 void f1(); 20 21 template<typename U> 22 void f2(U) { 23 f1<U>(); 24 } 25 }; 26 27 void 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. 32 template<typename F> 33 struct Y { 34 Y(const F&); 35 }; 36 37 template<int I> 38 struct 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 46 template struct X<3>; 47 48 // 'template' as a disambiguator. 49 // PR7030 50 struct 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 86 struct A { 87 template<int I> 88 struct B { 89 static void b1(); 90 }; 91 }; 92 93 template<int I> 94 void f5() { 95 A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}} 96 } 97 98 template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} 99