// 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*>&) ;