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