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

Reply via email to