[cfe-commits] r95629 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/SemaTemplate/temp_class_spec.cpp

Douglas Gregor dgregor at apple.com
Mon Feb 8 16:37:32 PST 2010


Author: dgregor
Date: Mon Feb  8 18:37:32 2010
New Revision: 95629

URL: http://llvm.org/viewvc/llvm-project?rev=95629&view=rev
Log:
Implement a specific diagnostic when a class template partial
specialization does not use any of its template parameters, then
recover far more gracefully. Fixes PR6181.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaTemplate/temp_class_spec.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=95629&r1=95628&r2=95629&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Feb  8 18:37:32 2010
@@ -1271,6 +1271,8 @@
   "class template partial specialization %0 cannot be redeclared">;
 def note_prev_partial_spec_here : Note<
   "previous declaration of class template partial specialization %0 is here">;
+def err_partial_spec_fully_specialized : Error<
+  "partial specialization of %0 does not use any of its template parameters">;
   
 // C++ Function template specializations
 def err_function_template_spec_no_match : Error<

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=95629&r1=95628&r2=95629&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Feb  8 18:37:32 2010
@@ -3400,12 +3400,23 @@
 
     // FIXME: Diagnose friend partial specializations
 
-    // FIXME: Template parameter list matters, too
-    ClassTemplatePartialSpecializationDecl::Profile(ID,
-                                                   Converted.getFlatArguments(),
-                                                   Converted.flatSize(),
-                                                    Context);
-  } else
+    if (!Name.isDependent() && 
+        !TemplateSpecializationType::anyDependentTemplateArguments(
+                                             TemplateArgs.getArgumentArray(), 
+                                                         TemplateArgs.size())) {
+      Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
+        << ClassTemplate->getDeclName();
+      isPartialSpecialization = false;
+    } else {
+      // FIXME: Template parameter list matters, too
+      ClassTemplatePartialSpecializationDecl::Profile(ID,
+                                                  Converted.getFlatArguments(),
+                                                      Converted.flatSize(),
+                                                      Context);
+    }
+  }
+  
+  if (!isPartialSpecialization)
     ClassTemplateSpecializationDecl::Profile(ID,
                                              Converted.getFlatArguments(),
                                              Converted.flatSize(),
@@ -3435,7 +3446,7 @@
   QualType CanonType;
   if (PrevDecl && 
       (PrevDecl->getSpecializationKind() == TSK_Undeclared ||
-       TUK == TUK_Friend)) {
+               TUK == TUK_Friend)) {
     // Since the only prior class template specialization with these
     // arguments was referenced but not declared, or we're only
     // referencing this specialization as a friend, reuse that
@@ -3448,8 +3459,8 @@
   } else if (isPartialSpecialization) {
     // Build the canonical type that describes the converted template
     // arguments of the class template partial specialization.
-    CanonType = Context.getTemplateSpecializationType(
-                                                  TemplateName(ClassTemplate),
+    TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
+    CanonType = Context.getTemplateSpecializationType(CanonTemplate,
                                                   Converted.getFlatArguments(),
                                                   Converted.flatSize());
 

Modified: cfe/trunk/test/SemaTemplate/temp_class_spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_class_spec.cpp?rev=95629&r1=95628&r2=95629&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_class_spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_class_spec.cpp Mon Feb  8 18:37:32 2010
@@ -348,3 +348,16 @@
   {
   };
 }
+
+namespace PR6181 {
+  template <class T>
+  class a;
+  
+  class s;
+  
+  template <class U>
+  class a<s> // expected-error{{partial specialization of 'a' does not use any of its template parameters}}
+  {
+  };
+  
+}





More information about the cfe-commits mailing list