[cfe-commits] r73260 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/temp_class_spec.cpp test/SemaTemplate/temp_class_spec_neg.cpp www/cxx_status.html

Douglas Gregor dgregor at apple.com
Fri Jun 12 15:21:45 PDT 2009


Author: dgregor
Date: Fri Jun 12 17:21:45 2009
New Revision: 73260

URL: http://llvm.org/viewvc/llvm-project?rev=73260&view=rev
Log:
Finish implementing checking of class template partial specializations

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaTemplate/temp_class_spec.cpp
    cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp
    cfe/trunk/www/cxx_status.html

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 12 17:21:45 2009
@@ -743,18 +743,19 @@
 def err_template_spec_extra_headers : Error<
   "template specialization must have a single 'template<>' header">;
 def err_template_spec_decl_out_of_scope_global : Error<
-  "class template specialization of %0 must occur in the global scope">;
+  "class template %select{|partial }0specialization of %1 must occur in the "
+  "global scope">;
 def err_template_spec_decl_out_of_scope : Error<
-  "class template specialization of %0 not in namespace %1">;
+  "class template %select{|partial }0specialization of %1 not in namespace %2">;
 def err_template_spec_decl_function_scope : Error<
-  "%select{class template specialization|explicit instantiation}0 of %1 "
-  "in function scope">;
+  "%select{class template specialization|class template partial specialization|"
+  "explicit instantiation}0 of %1 in function scope">;
 def err_template_spec_redecl_out_of_scope : Error<
-  "%select{class template specialization|explicit instantiation}0 of %1 "
-  "not in a namespace enclosing %2">;
+  "%select{class template specialization|class template partial specialization|"
+  "explicit instantiation}0 of %1 not in a namespace enclosing %2">;
 def err_template_spec_redecl_global_scope : Error<
-  "%select{class template specialization|explicit instantiation}0 of %1 must "
-  "occur at global scope">;
+  "%select{class template specialization|class template partial specialization|"
+  "explicit instantiation}0 of %1 must occur at global scope">;
 
 // C++ Class Template Partial Specialization
 def err_default_arg_in_partial_spec : Error<

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73260&r1=73259&r2=73260&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jun 12 17:21:45 2009
@@ -1950,6 +1950,7 @@
                                     ClassTemplateSpecializationDecl *PrevDecl,
                                              SourceLocation TemplateNameLoc,
                                              SourceRange ScopeSpecifierRange,
+                                             bool PartialSpecialization,
                                              bool ExplicitInstantiation);
 
   bool CheckClassTemplatePartialSpecializationArgs(

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Jun 12 17:21:45 2009
@@ -1932,6 +1932,7 @@
                                    ClassTemplateSpecializationDecl *PrevDecl,
                                             SourceLocation TemplateNameLoc,
                                             SourceRange ScopeSpecifierRange,
+                                            bool PartialSpecialization,
                                             bool ExplicitInstantiation) {
   // C++ [temp.expl.spec]p2:
   //   An explicit specialization shall be declared in the namespace
@@ -1947,8 +1948,9 @@
   //   that encloses the one in which the explicit specialization was
   //   declared.
   if (CurContext->getLookupContext()->isFunctionOrMethod()) {
+    int Kind = ExplicitInstantiation? 2 : PartialSpecialization? 1 : 0;
     Diag(TemplateNameLoc, diag::err_template_spec_decl_function_scope)
-      << ExplicitInstantiation << ClassTemplate;
+      << Kind << ClassTemplate;
     return true;
   }
 
@@ -1963,11 +1965,12 @@
     if (DC != TemplateContext) {
       if (isa<TranslationUnitDecl>(TemplateContext))
         Diag(TemplateNameLoc, diag::err_template_spec_decl_out_of_scope_global)
+          << PartialSpecialization
           << ClassTemplate << ScopeSpecifierRange;
       else if (isa<NamespaceDecl>(TemplateContext))
         Diag(TemplateNameLoc, diag::err_template_spec_decl_out_of_scope)
-          << ClassTemplate << cast<NamedDecl>(TemplateContext) 
-          << ScopeSpecifierRange;
+          << PartialSpecialization << ClassTemplate 
+          << cast<NamedDecl>(TemplateContext) << ScopeSpecifierRange;
 
       Diag(ClassTemplate->getLocation(), diag::note_template_decl_here);
     }
@@ -1981,16 +1984,17 @@
     // FIXME:  In C++98,  we  would like  to  turn these  errors into  warnings,
     // dependent on a -Wc++0x flag.
     bool SuppressedDiag = false;
+    int Kind = ExplicitInstantiation? 2 : PartialSpecialization? 1 : 0;
     if (isa<TranslationUnitDecl>(TemplateContext)) {
       if (!ExplicitInstantiation || getLangOptions().CPlusPlus0x)
         Diag(TemplateNameLoc, diag::err_template_spec_redecl_global_scope)
-          << ExplicitInstantiation << ClassTemplate << ScopeSpecifierRange;
+          << Kind << ClassTemplate << ScopeSpecifierRange;
       else
         SuppressedDiag = true;
     } else if (isa<NamespaceDecl>(TemplateContext)) {
       if (!ExplicitInstantiation || getLangOptions().CPlusPlus0x)
         Diag(TemplateNameLoc, diag::err_template_spec_redecl_out_of_scope)
-          << ExplicitInstantiation << ClassTemplate
+          << Kind << ClassTemplate
           << cast<NamedDecl>(TemplateContext) << ScopeSpecifierRange;
       else 
         SuppressedDiag = true;
@@ -2285,6 +2289,7 @@
   if (CheckClassTemplateSpecializationScope(ClassTemplate, PrevDecl,
                                             TemplateNameLoc, 
                                             SS.getRange(),
+                                            isPartialSpecialization,
                                             /*ExplicitInstantiation=*/false))
     return true;
 
@@ -2440,6 +2445,7 @@
   if (CheckClassTemplateSpecializationScope(ClassTemplate, 0,
                                             TemplateNameLoc, 
                                             SS.getRange(),
+                                            /*PartialSpecialization=*/false,
                                             /*ExplicitInstantiation=*/true))
     return true;
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri Jun 12 17:21:45 2009
@@ -854,8 +854,11 @@
   const TemplateArgumentList *TemplateArgs 
     = &ClassTemplateSpec->getTemplateArgs();
 
-  // Determine whether any class template partial specializations
-  // match the given template arguments.
+  // C++ [temp.class.spec]p7:
+  //   Partial specialization declarations themselves are not found by
+  //   name lookup. Rather, when the primary template name is used,
+  //   any previously declared partial specializations of the primary
+  //   template are also considered.
   typedef std::pair<ClassTemplatePartialSpecializationDecl *,
                     TemplateArgumentList *> MatchResult;
   llvm::SmallVector<MatchResult, 4> Matched;

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=73260&r1=73259&r2=73260&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_class_spec.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_class_spec.cpp Fri Jun 12 17:21:45 2009
@@ -255,3 +255,10 @@
 //int is_nested_value_type_identity2[
 //                   is_nested_value_type_identity<NoValueType>::value? -1 : 1];
 
+
+// C++ [temp.class.spec]p4:
+template<class T1, class T2, int I> class A { }; //#1 
+template<class T, int I> class A<T, T*, I> { }; //#2 
+template<class T1, class T2, int I> class A<T1*, T2, I> { }; //#3 
+template<class T> class A<int, T*, 5> { }; //#4 
+template<class T1, class T2, int I> class A<T1, T2*, I> { }; //#5 

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

==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_class_spec_neg.cpp Fri Jun 12 17:21:45 2009
@@ -1,8 +1,17 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 template<typename T> struct vector;
 
-// C++ [temp.class.spec]p9
+// C++ [temp.class.spec]p6:
+namespace N {
+  namespace M {
+    template<typename T> struct A; // expected-note{{here}}
+  }
+}
+
+template<typename T>
+struct N::M::A<T*> { }; // expected-error{{not in namespace}}
 
+// C++ [temp.class.spec]p9
 //   bullet 1
 template <int I, int J> struct A {}; 
 template <int I> struct A<I+5, I*2> {}; // expected-error{{depends on}} 

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=73260&r1=73259&r2=73260&view=diff

==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Fri Jun 12 17:21:45 2009
@@ -1887,7 +1887,7 @@
   <td>    14.5.4 [temp.class.spec]</td>
   <td class="complete" align="center"></td>  
   <td class="complete" align="center"></td>
-  <td class="medium" align="center"></td>
+  <td class="complete" align="center"></td>
   <td class="na" align="center">N/A</td>
   <td></td>
 </tr>





More information about the cfe-commits mailing list