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