1 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %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 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'. 22 template class X0<double> { }; // expected-error{{explicit specialization}} 23 24 // Check for explicit instantiations that come after other kinds of 25 // instantiations or declarations. 26 template class X0<int, int>; // expected-error{{duplicate}} 27 28 template<> class X0<char> { }; // expected-note{{previous}} 29 template class X0<char>; // expected-warning{{ignored}} 30 31 void foo(X0<short>) { } 32 template 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. 37 template<typename T> struct X2; // expected-note{{declared here}} 38 39 template struct X2<float>; // expected-error{{undefined template}} 40 41 template<typename T> 42 struct X2 { 43 void f0(T*); // expected-error{{pointer to a reference}} 44 }; 45 46 template struct X2<int>; // okay 47 template struct X2<int&>; // expected-note{{in instantiation of}} 48 49 // Check that explicit instantiations instantiate member classes. 50 template<typename T> struct X3 { 51 struct Inner { 52 void f(T*); // expected-error{{pointer to a reference}} 53 }; 54 }; 55 56 void f1(X3<int&>); // okay, Inner, not instantiated 57 58 template struct X3<int&>; // expected-note{{instantiation}} 59 60 template<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 68 void f2(X4<int&>); // okay, Inner, not instantiated 69 void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated 70 71 template struct X4<int&>; // expected-note{{instantiation}} 72 template struct X4<float&>; // expected-note{{instantiation}} 73 74 // Check explicit instantiation of member classes 75 namespace N2 { 76 77 template<typename T> 78 struct X5 { 79 struct Inner1 { 80 void f(T&); 81 }; 82 83 struct Inner2 { // expected-note {{here}} 84 struct VeryInner { 85 void g(T*); // expected-error 2{{pointer to a reference}} 86 }; 87 }; 88 }; 89 90 } 91 92 template struct N2::X5<void>::Inner2; 93 94 using namespace N2; 95 template struct X5<int&>::Inner2; // expected-note{{instantiation}} 96 97 void f4(X5<float&>::Inner2); 98 template struct X5<float&>::Inner2; // expected-note{{instantiation}} 99 100 namespace N3 { 101 template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}} 102 } 103 104 struct X6 { 105 struct Inner { // expected-note{{here}} 106 void f(); 107 }; 108 }; 109 110 template struct X6::Inner; // expected-error{{non-templated}} 111 112 // PR5559 113 template <typename T> 114 struct Foo; 115 116 template <> 117 struct Foo<int> // expected-note{{header not required for explicitly-specialized}} 118 { 119 template <typename U> 120 struct Bar 121 {}; 122 }; 123 124 template <> // expected-warning{{extraneous template parameter list}} 125 template <> 126 struct Foo<int>::Bar<void> 127 {}; 128 129 namespace N1 { 130 131 template<typename T> struct X7 { }; // expected-note{{here}} 132 133 namespace Inner { 134 template<typename T> struct X8 { }; 135 } 136 137 template struct X7<int>; 138 template struct Inner::X8<int>; 139 } 140 141 template<typename T> struct X9 { }; // expected-note{{here}} 142 143 template struct ::N1::Inner::X8<float>; 144 145 namespace N2 { 146 using namespace N1; 147 148 template struct X7<double>; // expected-warning{{must occur in namespace}} 149 150 template struct X9<float>; // expected-warning{{must occur at global scope}} 151 } 152