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