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:
Douglas Gregor 2009-10-06 21:27:51 +00:00
parent 3251776d1d
commit 27c26e9a09
2 changed files with 98 additions and 1 deletions

View File

@ -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;
}

View File

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