diff options
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 9 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.class.spec/p6.cpp | 20 |
3 files changed, 41 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 1addd16bdf..9d7dd0a056 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2434,11 +2434,19 @@ static bool CheckTemplateSpecializationScope(Sema &S, return true; } + // FIXME: For everything except class template partial specializations, + // complain if the explicit specialization/instantiation occurs at class + // scope. + + // C++ [temp.class.spec]p6: + // A class template partial specialization may be declared or redeclared + // in any namespace scope in which its definition may be defined (14.5.1 + // and 14.5.2). bool ComplainedAboutScope = false; - DeclContext *SpecializedContext + DeclContext *SpecializedContext = Specialized->getDeclContext()->getEnclosingNamespaceContext(); + DeclContext *DC = S.CurContext->getEnclosingNamespaceContext(); if (TSK == TSK_ExplicitSpecialization) { - DeclContext *DC = S.CurContext->getEnclosingNamespaceContext(); if ((!PrevDecl || getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared || getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){ @@ -2468,8 +2476,8 @@ static bool CheckTemplateSpecializationScope(Sema &S, // specializations of function templates, static data members, and member // functions, so we skip the check here for those kinds of entities. // FIXME: HandleDeclarator's diagnostics aren't quite as good, though. - // Should we refactor the check, so that it occurs later? - if (!ComplainedAboutScope && !S.CurContext->Encloses(SpecializedContext) && + // Should we refactor that check, so that it occurs later? + if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) && ((TSK == TSK_ExplicitSpecialization && !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) || isa<FunctionDecl>(Specialized))) || diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 53252ec3f7..fa30365941 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -57,6 +57,8 @@ namespace { ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D); Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D); Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); + Decl *VisitClassTemplatePartialSpecializationDecl( + ClassTemplatePartialSpecializationDecl *D); Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); Decl *VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D); @@ -401,6 +403,13 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { } Decl * +TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( + ClassTemplatePartialSpecializationDecl *D) { + assert(false &&"Partial specializations of member templates are unsupported"); + return 0; +} + +Decl * TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { // FIXME: Dig out the out-of-line definition of this function template? diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp new file mode 100644 index 0000000000..afe6ab2b96 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> +struct X0 { + template<typename U> struct Inner0 { + static const unsigned value = 0; + }; + + template<typename U> struct Inner0<U*> { + static const unsigned value = 1; + }; +}; + +template<typename T> template<typename U> +struct X0<T>::Inner0<const U*> { + static const unsigned value = 2; +}; + +// FIXME: Test instantiation of these partial specializations (once they are +// implemented). |