[PATCH] Partial specialization after class template instantiation.
Anton Bikineev
ant.bikineev at gmail.com
Fri Apr 10 13:23:02 PDT 2015
Applied some comments
http://reviews.llvm.org/D5744
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaTemplate.cpp
test/SemaTemplate/class-template-spec.cpp
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -3392,6 +3392,8 @@
def note_specialized_decl : Note<"attempt to specialize declaration here">;
def err_specialization_after_instantiation : Error<
"explicit specialization of %0 after instantiation">;
+def err_partial_spec_after_instantiation : Error<
+ "partial specialization of %0 after instantiation">;
def note_instantiation_required_here : Note<
"%select{implicit|explicit}0 instantiation first required here">;
def err_template_spec_friend : Error<
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -6217,6 +6217,38 @@
CanonType = Context.getTypeDeclType(Specialization);
}
+ // C++ [temp.class.spec]p1:
+ // A partial specialization shall be declared before the first use of a class
+ // template specialization that would make use of partial specialization as
+ // the result of an implicit or explicit instantiation in every translation
+ // unit in which such a use occurs; no diagnostic is required.
+ if (isPartialSpecialization && !PrevDecl) {
+ auto *ThisPartialSpec =
+ cast<ClassTemplatePartialSpecializationDecl>(Specialization);
+ for (const auto &S : ClassTemplate->specializations()) {
+ TemplateDeductionInfo Info(KWLoc);
+ if (S->getSpecializationKind() != TSK_ExplicitSpecialization &&
+ S->hasDefinition() &&
+ !DeduceTemplateArguments(ThisPartialSpec, S->getTemplateArgs(), Info)) {
+ auto *InstantiatedFrom =
+ S->getInstantiatedFrom()
+ .dyn_cast<ClassTemplatePartialSpecializationDecl *>();
+ if (!InstantiatedFrom ||
+ getMoreSpecializedPartialSpecialization(
+ ThisPartialSpec, InstantiatedFrom, KWLoc) == ThisPartialSpec) {
+ SourceRange Range(TemplateNameLoc, RAngleLoc);
+ Diag(TemplateNameLoc, diag::err_partial_spec_after_instantiation)
+ << Context.getTypeDeclType(ThisPartialSpec) << Range;
+
+ Diag(S->getPointOfInstantiation(),
+ diag::note_instantiation_required_here)
+ << (S->getTemplateSpecializationKind() !=
+ TSK_ImplicitInstantiation);
+ }
+ }
+ }
+ }
+
// C++ [temp.expl.spec]p6:
// If a template, a member template or the member of a class template is
// explicitly specialized then that specialization shall be declared
Index: test/SemaTemplate/class-template-spec.cpp
===================================================================
--- test/SemaTemplate/class-template-spec.cpp
+++ test/SemaTemplate/class-template-spec.cpp
@@ -177,3 +177,16 @@
> struct S;
template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
}
+
+namespace PartialSpecAfterInstantiation {
+ template <typename T> struct A {};
+
+ A<int*> a; // expected-note {{implicit instantiation}}
+ template <typename T> struct A<T*> {}; // expected-error {{partial specialization}}
+
+ template struct A<int&>; // expected-note {{explicit instantiation}}
+ template <typename T> struct A<T&> {}; // expected-error {{partial specialization}}
+
+ A<const int*>* b; // that's fine
+ template <typename T> struct A<const T*> {};
+}
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D5744.23617.patch
Type: text/x-patch
Size: 3529 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150410/772d65cf/attachment.bin>
More information about the cfe-commits
mailing list