Hi rsmith, nikola,
http://reviews.llvm.org/D5744
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaTemplate.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_part_specialization_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,39 @@
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) {
+ auto *const ThisPartialSpec =
+ static_cast<ClassTemplatePartialSpecializationDecl *>(Specialization);
+ for (auto S = ClassTemplate->spec_begin(), SEnd = ClassTemplate->spec_end();
+ S != SEnd; ++S) {
+ TemplateDeductionInfo Info(KWLoc);
+ if (S->getSpecializationKind() != TSK_ExplicitSpecialization &&
+ S->hasDefinition() &&
+ !DeduceTemplateArguments(ThisPartialSpec, S->getTemplateArgs(), Info)) {
+ auto *const InstantiatedFrom =
+ S->getInstantiatedFrom()
+ .dyn_cast<ClassTemplatePartialSpecializationDecl *>();
+ if (!InstantiatedFrom ||
+ getMoreSpecializedPartialSpecialization(
+ ThisPartialSpec, InstantiatedFrom, KWLoc) == ThisPartialSpec) {
+ SourceRange Range(TemplateNameLoc, RAngleLoc);
+ Diag(TemplateNameLoc, diag::err_part_specialization_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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits