forked from OSchip/llvm-project
Test explicit specialization for all of the various cases where
explicit specializations can occur. Also, fix a minor recovery bug where we should allow declarations coming from the parser to be NULL. llvm-svn: 83416
This commit is contained in:
parent
3251776d1d
commit
27c26e9a09
|
@ -257,7 +257,7 @@ bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
|
|||
/// the parameter D to reference the templated declaration and return a pointer
|
||||
/// to the template declaration. Otherwise, do nothing to D and return null.
|
||||
TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
|
||||
if (TemplateDecl *Temp = dyn_cast<TemplateDecl>(D.getAs<Decl>())) {
|
||||
if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D.getAs<Decl>())) {
|
||||
D = DeclPtrTy::make(Temp->getTemplatedDecl());
|
||||
return Temp;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
// RUN: clang-cc -fsyntax-only %s
|
||||
|
||||
// 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
|
||||
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*>&) ;
|
Loading…
Reference in New Issue