p2.cpp revision 1fef4e60e7e884803977a8376c172ea584f8a5d1
1// RUN: clang-cc -fsyntax-only -verify %s 2 3// This test creates cases where implicit instantiations of various entities 4// would cause a diagnostic, but provides expliict specializations for those 5// entities that avoid the diagnostic. The specializations are alternately 6// declarations and definitions, and the intent of this test is to verify 7// that we allow specializations only in the appropriate namespaces (and 8// nowhere else). 9struct NonDefaultConstructible { 10 NonDefaultConstructible(int); 11}; 12 13 14// C++ [temp.expl.spec]p1: 15// An explicit specialization of any of the following: 16 17// -- function template 18namespace N0 { 19 template<typename T> void f0(T) { // expected-note{{here}} 20 T t; 21 } 22 23 template<> void f0(NonDefaultConstructible) { } 24 25 void test_f0(NonDefaultConstructible NDC) { 26 f0(NDC); 27 } 28 29 template<> void f0(int); 30 template<> void f0(long); 31} 32 33template<> void N0::f0(int) { } // okay 34 35namespace N1 { 36 template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}} 37} 38 39template<> void N0::f0(double) { } // expected-error{{originally be declared}} 40 41struct X1 { 42 template<typename T> void f(T); 43 44 template<> void f(int); // expected-error{{in class scope}} 45}; 46 47// -- class template 48namespace N0 { 49 50template<typename T> 51struct X0 { // expected-note 2{{here}} 52 static T member; 53 54 void f1(T t) { // expected-note{{explicitly specialized declaration is here}} 55 t = 17; 56 } 57 58 struct Inner : public T { }; 59 60 template<typename U> 61 struct InnerTemplate : public T { }; 62 63 template<typename U> 64 void ft1(T t, U u); 65}; 66 67} 68 69template<typename T> 70template<typename U> 71void N0::X0<T>::ft1(T t, U u) { 72 t = u; 73} 74 75template<typename T> T N0::X0<T>::member; 76 77template<> struct N0::X0<void> { }; // expected-error{{originally}} 78N0::X0<void> test_X0; 79 80namespace N1 { 81 template<> struct N0::X0<const void> { }; // expected-error{{originally}} 82} 83 84namespace N0 { 85 template<> struct X0<volatile void>; 86} 87 88template<> struct N0::X0<volatile void> { 89 void f1(void *); 90}; 91 92// -- member function of a class template 93template<> void N0::X0<void*>::f1(void *) { } // expected-error{{member function specialization}} 94 95void test_spec(N0::X0<void*> xvp, void *vp) { 96 xvp.f1(vp); 97} 98 99namespace N0 { 100 template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}} 101} 102 103#if 0 104// FIXME: update the remainder of this test to check for scopes properly. 105// -- static data member of a class template 106template<> 107NonDefaultConstructible X0<NonDefaultConstructible>::member = 17; 108 109NonDefaultConstructible &get_static_member() { 110 return X0<NonDefaultConstructible>::member; 111} 112 113// -- member class of a class template 114template<> 115struct X0<void*>::Inner { }; 116 117X0<void*>::Inner inner0; 118 119// -- member class template of a class template 120template<> 121template<> 122struct X0<void*>::InnerTemplate<int> { }; 123 124X0<void*>::InnerTemplate<int> inner_template0; 125 126// -- member function template of a class template 127template<> 128template<> 129void X0<void*>::ft1(void*, const void*) { } 130 131void test_func_template(X0<void *> xvp, void *vp, const void *cvp) { 132 xvp.ft1(vp, cvp); 133} 134#endif 135