[cfe-commits] r105464 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp

Douglas Gregor dgregor at apple.com
Fri Jun 4 01:34:33 PDT 2010


Author: dgregor
Date: Fri Jun  4 03:34:32 2010
New Revision: 105464

URL: http://llvm.org/viewvc/llvm-project?rev=105464&view=rev
Log:
When checking for equality of template parameter lists, a template
type parameter pack is distinct from a template type parameter.

Added:
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp   (with props)
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=105464&r1=105463&r2=105464&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun  4 03:34:32 2010
@@ -1234,6 +1234,7 @@
   "%select{|template parameter }0redeclaration">;
 def note_template_param_different_kind : Note<
   "template parameter has a different kind in template argument">;
+  
 def err_template_nontype_parm_different_type : Error<
   "template non-type parameter has a different type %0 in template "
   "%select{|template parameter }1redeclaration">;
@@ -1606,6 +1607,18 @@
 def err_template_param_pack_must_be_last_template_parameter : Error<
   "template parameter pack must be the last template parameter">;
 
+def err_template_parameter_pack_non_pack : Error<
+  "template %select{type|non-type|template}0 parameter%select{| pack}1 "
+  "conflicts with previous template %select{type|non-type|template}0 "
+  "parameter%select{ pack|}1">;
+def note_template_parameter_pack_non_pack : Note<
+  "template %select{type|non-type|template}0 parameter%select{| pack}1 "
+  "does not match template %select{type|non-type|template}0 "
+  "parameter%select{ pack|}1 in template argument">;
+def note_template_parameter_pack_here : Note<
+  "previous template %select{type|non-type|template}0 "
+  "parameter%select{| pack}1 declared here">;
+  
 def err_unexpected_typedef : Error<
   "unexpected type name %0: expected expression">;
 def err_unexpected_namespace : Error<

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=105464&r1=105463&r2=105464&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Jun  4 03:34:32 2010
@@ -3237,9 +3237,32 @@
       return false;
     }
 
-    if (isa<TemplateTypeParmDecl>(*OldParm)) {
-      // Okay; all template type parameters are equivalent (since we
-      // know we're at the same index).
+    if (TemplateTypeParmDecl *OldTTP
+                                  = dyn_cast<TemplateTypeParmDecl>(*OldParm)) {
+      // Template type parameters are equivalent if either both are template
+      // type parameter packs or neither are (since we know we're at the same 
+      // index).
+      TemplateTypeParmDecl *NewTTP = cast<TemplateTypeParmDecl>(*NewParm);
+      if (OldTTP->isParameterPack() != NewTTP->isParameterPack()) {
+        // FIXME: Implement the rules in C++0x [temp.arg.template]p5 that
+        // allow one to match a template parameter pack in the template
+        // parameter list of a template template parameter to one or more
+        // template parameters in the template parameter list of the 
+        // corresponding template template argument.        
+        if (Complain) {
+          unsigned NextDiag = diag::err_template_parameter_pack_non_pack;
+          if (TemplateArgLoc.isValid()) {
+            Diag(TemplateArgLoc,
+                 diag::err_template_arg_template_params_mismatch);
+            NextDiag = diag::note_template_parameter_pack_non_pack;
+          }
+          Diag(NewTTP->getLocation(), NextDiag)
+            << 0 << NewTTP->isParameterPack();
+          Diag(OldTTP->getLocation(), diag::note_template_parameter_pack_here)
+            << 0 << OldTTP->isParameterPack();
+        }
+        return false;
+      }
     } else if (NonTypeTemplateParmDecl *OldNTTP
                  = dyn_cast<NonTypeTemplateParmDecl>(*OldParm)) {
       // The types of non-type template parameters must agree.

Added: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp?rev=105464&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp Fri Jun  4 03:34:32 2010
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Check for template type parameter pack (mis-)matches with template
+// type parameters.
+template<typename ...T> struct X0t;
+template<typename ...T> struct X0t;
+
+template<typename ...T> struct X1t; // expected-note{{previous template type parameter pack declared here}}
+template<typename T> struct X1t; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
+
+template<typename T> struct X2t; // expected-note{{previous template type parameter declared here}}
+template<typename ...T> struct X2t; // expected-error{{template type parameter pack conflicts with previous template type parameter}}
+
+template<template<typename ...T> class> struct X0tt; 
+template<template<typename ...T> class> struct X0tt; 
+
+template<template<typename ...T> class> struct X1tt; // expected-note{{previous template type parameter pack declared here}}
+template<template<typename T> class> struct X1tt; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
+
+template<template<typename T> class> struct X2tt; // expected-note{{previous template type parameter declared here}}
+template<template<typename ...T> class> struct X2tt; // expected-error{{template type parameter pack conflicts with previous template type parameter}}

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list