1 // RUN: clang-cc -fsyntax-only -pedantic -verify %s 2 // 3 // Tests explicit instantiation of templates. 4 template<typename T, typename U = T> class X0 { }; 5 6 namespace N { 7 template<typename T, typename U = T> class X1 { }; 8 } 9 10 // Check the syntax of explicit instantiations. 11 template class X0<int, float>; 12 template class X0<int>; // expected-note{{previous}} 13 14 template class N::X1<int>; 15 template class ::N::X1<int, float>; 16 17 using namespace N; 18 template class X1<float>; 19 20 // Check for some bogus syntax that probably means that the user 21 // wanted to write an explicit specialization, but forgot the '<>' 22 // after 'template'. 23 template class X0<double> { }; // expected-error{{explicit specialization}} 24 25 // Check for explicit instantiations that come after other kinds of 26 // instantiations or declarations. 27 template class X0<int, int>; // expected-error{{duplicate}} 28 29 template<> class X0<char> { }; // expected-note{{previous}} 30 template class X0<char>; // expected-warning{{ignored}} 31 32 void foo(X0<short>) { } 33 template class X0<short>; 34 35 // Check that explicit instantiations actually produce definitions. We 36 // determine whether this happens by placing semantic errors in the 37 // definition of the template we're instantiating. 38 template<typename T> struct X2; // expected-note{{declared here}} 39 40 template struct X2<float>; // expected-error{{undefined template}} 41 42 template<typename T> 43 struct X2 { 44 void f0(T*); // expected-error{{pointer to a reference}} 45 }; 46 47 template struct X2<int>; // okay 48 template struct X2<int&>; // expected-note{{in instantiation of}} 49 50 // Check that explicit instantiations instantiate member classes. 51 template<typename T> struct X3 { 52 struct Inner { 53 void f(T*); // expected-error{{pointer to a reference}} 54 }; 55 }; 56 57 void f1(X3<int&>); // okay, Inner, not instantiated 58 59 template struct X3<int&>; // expected-note{{instantiation}} 60 61 template<typename T> struct X4 { 62 struct Inner { 63 struct VeryInner { 64 void f(T*); // expected-error 2{{pointer to a reference}} 65 }; 66 }; 67 }; 68 69 void f2(X4<int&>); // okay, Inner, not instantiated 70 void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated 71 72 template struct X4<int&>; // expected-note{{instantiation}} 73 template struct X4<float&>; // expected-note{{instantiation}} 74 75 // Check explicit instantiation of member classes 76 namespace N2 { 77 78 template<typename T> 79 struct X5 { 80 struct Inner1 { 81 void f(T&); 82 }; 83 84 struct Inner2 { 85 struct VeryInner { 86 void g(T*); // expected-error 2{{pointer to a reference}} 87 }; 88 }; 89 }; 90 91 } 92 93 template struct N2::X5<void>::Inner2; 94 95 using namespace N2; 96 template struct X5<int&>::Inner2; // expected-note{{instantiation}} 97 98 void f4(X5<float&>::Inner2); 99 template struct X5<float&>::Inner2; // expected-note{{instantiation}} 100 101 namespace N3 { 102 template struct N2::X5<int>::Inner2; 103 } 104 105 struct X6 { 106 struct Inner { // expected-note{{here}} 107 void f(); 108 }; 109 }; 110 111 template struct X6::Inner; // expected-error{{non-templated}} 112