| // RUN: %clang_cc1 -fsyntax-only -verify %s |
| // expected-no-diagnostics |
| |
| // This test creates cases where implicit instantiations of various entities |
| // would cause a diagnostic, but provides expliict specializations for those |
| // entities that avoid the diagnostic. The intent is to verify that |
| // implicit instantiations do not occur (because the explicit specialization |
| // is used instead). |
| struct NonDefaultConstructible { |
| NonDefaultConstructible(int); |
| }; |
| |
| |
| // C++ [temp.expl.spec]p1: |
| // An explicit specialization of any of the following: |
| |
| // -- function template |
| template<typename T> void f0(T) { |
| T t; |
| } |
| |
| template<> void f0(NonDefaultConstructible) { } |
| |
| void test_f0(NonDefaultConstructible NDC) { |
| f0(NDC); |
| } |
| |
| // -- class template |
| template<typename T> |
| struct X0 { |
| static T member; |
| |
| void f1(T t) { |
| t = 17; |
| } |
| |
| struct Inner : public T { }; |
| |
| template<typename U> |
| struct InnerTemplate : public T { }; |
| |
| template<typename U> |
| void ft1(T t, U u); |
| }; |
| |
| template<typename T> |
| template<typename U> |
| void X0<T>::ft1(T t, U u) { |
| t = u; |
| } |
| |
| template<typename T> T X0<T>::member; |
| |
| template<> struct X0<void> { }; |
| X0<void> test_X0; |
| |
| |
| // -- member function of a class template |
| template<> void X0<void*>::f1(void *) { } |
| |
| void test_spec(X0<void*> xvp, void *vp) { |
| xvp.f1(vp); |
| } |
| |
| // -- static data member of a class template |
| template<> |
| NonDefaultConstructible X0<NonDefaultConstructible>::member = 17; |
| |
| NonDefaultConstructible &get_static_member() { |
| return X0<NonDefaultConstructible>::member; |
| } |
| |
| // -- member class of a class template |
| template<> |
| struct X0<void*>::Inner { }; |
| |
| X0<void*>::Inner inner0; |
| |
| // -- member class template of a class template |
| template<> |
| template<> |
| struct X0<void*>::InnerTemplate<int> { }; |
| |
| X0<void*>::InnerTemplate<int> inner_template0; |
| |
| // -- member function template of a class template |
| template<> |
| template<> |
| void X0<void*>::ft1(void*, const void*) { } |
| |
| void test_func_template(X0<void *> xvp, void *vp, const void *cvp) { |
| xvp.ft1(vp, cvp); |
| } |
| |
| // example from the standard: |
| template<class T> class stream; |
| template<> class stream<char> { /* ... */ }; |
| template<class T> class Array { /* ... */ }; |
| template<class T> void sort(Array<T>& v) { /* ... */ } |
| template<> void sort<char*>(Array<char*>&) ; |