101 lines
2.2 KiB
C++
101 lines
2.2 KiB
C++
|
// 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*>&) ;
|