1// RUN: %clang_cc1 -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 intent is to verify that 6// implicit instantiations do not occur (because the explicit specialization 7// is used instead). 8struct NonDefaultConstructible { 9 NonDefaultConstructible(int); 10}; 11 12 13// C++ [temp.expl.spec]p1: 14// An explicit specialization of any of the following: 15 16// -- function template 17template<typename T> void f0(T) { 18 T t; 19} 20 21template<> void f0(NonDefaultConstructible) { } 22 23void test_f0(NonDefaultConstructible NDC) { 24 f0(NDC); 25} 26 27// -- class template 28template<typename T> 29struct X0 { 30 static T member; 31 32 void f1(T t) { 33 t = 17; 34 } 35 36 struct Inner : public T { }; 37 38 template<typename U> 39 struct InnerTemplate : public T { }; 40 41 template<typename U> 42 void ft1(T t, U u); 43}; 44 45template<typename T> 46template<typename U> 47void X0<T>::ft1(T t, U u) { 48 t = u; 49} 50 51template<typename T> T X0<T>::member; 52 53template<> struct X0<void> { }; 54X0<void> test_X0; 55 56 57// -- member function of a class template 58template<> void X0<void*>::f1(void *) { } 59 60void test_spec(X0<void*> xvp, void *vp) { 61 xvp.f1(vp); 62} 63 64// -- static data member of a class template 65template<> 66NonDefaultConstructible X0<NonDefaultConstructible>::member = 17; 67 68NonDefaultConstructible &get_static_member() { 69 return X0<NonDefaultConstructible>::member; 70} 71 72// -- member class of a class template 73template<> 74struct X0<void*>::Inner { }; 75 76X0<void*>::Inner inner0; 77 78// -- member class template of a class template 79template<> 80template<> 81struct X0<void*>::InnerTemplate<int> { }; 82 83X0<void*>::InnerTemplate<int> inner_template0; 84 85// -- member function template of a class template 86template<> 87template<> 88void X0<void*>::ft1(void*, const void*) { } 89 90void test_func_template(X0<void *> xvp, void *vp, const void *cvp) { 91 xvp.ft1(vp, cvp); 92} 93 94// example from the standard: 95template<class T> class stream; 96template<> class stream<char> { /* ... */ }; 97template<class T> class Array { /* ... */ }; 98template<class T> void sort(Array<T>& v) { /* ... */ } 99template<> void sort<char*>(Array<char*>&) ; 100