1 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s 2 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat -std=c++98 %s 3 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=c++11 %s 4 // 5 // Tests explicit instantiation of templates. 6 template<typename T, typename U = T> class X0 { }; 7 8 namespace N { 9 template<typename T, typename U = T> class X1 { }; 10 } 11 12 // Check the syntax of explicit instantiations. 13 template class X0<int, float>; 14 template class X0<int>; // expected-note{{previous}} 15 16 template class N::X1<int>; 17 template class ::N::X1<int, float>; 18 19 using namespace N; 20 21 // Check for some bogus syntax that probably means that the user 22 // wanted to write an explicit specialization, but forgot the '<>' 23 // after 'template'. 24 template class X0<double> { }; // expected-error{{explicit specialization}} 25 26 // Check for explicit instantiations that come after other kinds of 27 // instantiations or declarations. 28 template class X0<int, int>; // expected-error{{duplicate}} 29 30 template<> class X0<char> { }; // expected-note{{previous}} 31 template class X0<char>; // expected-warning{{has no effect}} 32 33 void foo(X0<short>) { } 34 template class X0<short>; 35 36 // Check that explicit instantiations actually produce definitions. We 37 // determine whether this happens by placing semantic errors in the 38 // definition of the template we're instantiating. 39 template<typename T> struct X2; // expected-note{{declared here}} 40 41 template struct X2<float>; // expected-error{{undefined template}} 42 43 template<typename T> 44 struct X2 { 45 void f0(T*); // expected-error{{pointer to a reference}} 46 }; 47 48 template struct X2<int>; // okay 49 template struct X2<int&>; // expected-note{{in instantiation of}} 50 51 // Check that explicit instantiations instantiate member classes. 52 template<typename T> struct X3 { 53 struct Inner { 54 void f(T*); // expected-error{{pointer to a reference}} 55 }; 56 }; 57 58 void f1(X3<int&>); // okay, Inner, not instantiated 59 60 template struct X3<int&>; // expected-note{{instantiation}} 61 62 template<typename T> struct X4 { 63 struct Inner { 64 struct VeryInner { 65 void f(T*); // expected-error 2{{pointer to a reference}} 66 }; 67 }; 68 }; 69 70 void f2(X4<int&>); // okay, Inner, not instantiated 71 void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated 72 73 template struct X4<int&>; // expected-note{{instantiation}} 74 template struct X4<float&>; // expected-note{{instantiation}} 75 76 // Check explicit instantiation of member classes 77 namespace N2 { 78 79 template<typename T> 80 struct X5 { 81 struct Inner1 { 82 void f(T&); 83 }; 84 85 struct Inner2 { // expected-note {{here}} 86 struct VeryInner { 87 void g(T*); // expected-error 2{{pointer to a reference}} 88 }; 89 }; 90 }; 91 92 } 93 94 template struct N2::X5<void>::Inner2; 95 96 using namespace N2; 97 template struct X5<int&>::Inner2; // expected-note{{instantiation}} 98 99 void f4(X5<float&>::Inner2); 100 template struct X5<float&>::Inner2; // expected-note{{instantiation}} 101 102 namespace N3 { 103 template struct N2::X5<int>::Inner2; 104 #if __cplusplus <= 199711L 105 // expected-warning@-2 {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}} 106 #else 107 // expected-error@-4 {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}} 108 #endif 109 } 110 111 struct X6 { 112 struct Inner { // expected-note{{here}} 113 void f(); 114 }; 115 }; 116 117 template struct X6::Inner; // expected-error{{non-templated}} 118 119 // PR5559 120 template <typename T> 121 struct Foo; 122 123 template <> 124 struct Foo<int> // expected-note{{header not required for explicitly-specialized}} 125 { 126 template <typename U> 127 struct Bar 128 {}; 129 }; 130 131 template <> // expected-warning{{extraneous template parameter list}} 132 template <> 133 struct Foo<int>::Bar<void> 134 {}; 135 136 namespace N1 { 137 138 template<typename T> struct X7 { }; // expected-note{{here}} 139 140 namespace Inner { 141 template<typename T> struct X8 { }; 142 } 143 144 template struct X7<int>; 145 template struct Inner::X8<int>; 146 } 147 148 template<typename T> struct X9 { }; // expected-note{{here}} 149 150 template struct ::N1::Inner::X8<float>; 151 152 namespace N2 { 153 using namespace N1; 154 155 template struct X7<double>; 156 #if __cplusplus <= 199711L 157 // expected-warning@-2 {{explicit instantiation of 'N1::X7' must occur in namespace 'N1'}} 158 #else 159 // expected-error@-4 {{explicit instantiation of 'N1::X7' must occur in namespace 'N1'}} 160 #endif 161 162 template struct X9<float>; 163 #if __cplusplus <= 199711L 164 // expected-warning@-2 {{explicit instantiation of 'X9' must occur at global scope}} 165 #else 166 // expected-error@-4 {{explicit instantiation of 'X9' must occur at global scope}} 167 #endif 168 } 169