+2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/34314
+ * error.c (dump_simple_decl): Display ellipsis for template
+ non-type parameter packs.
+ (dump_decl): Display ellipsis for template type parameter packs.
+ (dump_template_decl): Display ellipsis for template template
+ parameter packs.
+ * pt.c (redeclare_class_template): When redeclaring a class
+ template, check for collisions between template parameters and
+ template parameter packs.
+
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33964
|| TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
dump_scope (CP_DECL_CONTEXT (t), flags);
flags &= ~TFF_UNQUALIFIED_NAME;
+ if ((flags & TFF_DECL_SPECIFIERS)
+ && DECL_TEMPLATE_PARM_P (t)
+ && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
+ pp_identifier (cxx_pp, "...");
if (DECL_NAME (t))
dump_decl (DECL_NAME (t), flags);
else
{
if ((flags & TFF_DECL_SPECIFIERS)
&& TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
- /* Say `class T' not just `T'. */
- pp_cxx_identifier (cxx_pp, "class");
+ {
+ /* Say `class T' not just `T'. */
+ pp_cxx_identifier (cxx_pp, "class");
+
+ /* Emit the `...' for a parameter pack. */
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ pp_cxx_identifier (cxx_pp, "...");
+ }
dump_type (TREE_TYPE (t), flags);
break;
nreverse(orig_parms);
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
- /* Say `template<arg> class TT' not just `template<arg> TT'. */
- pp_cxx_identifier (cxx_pp, "class");
+ {
+ /* Say `template<arg> class TT' not just `template<arg> TT'. */
+ pp_cxx_identifier (cxx_pp, "class");
+
+ /* If this is a parameter pack, print the ellipsis. */
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+ pp_cxx_identifier (cxx_pp, "...");
+ }
}
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
/* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
TEMPLATE_DECL. */
if (tmpl_parm != error_mark_node
- && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
- || (TREE_CODE (tmpl_parm) != TYPE_DECL
- && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
+ && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+ || (TREE_CODE (tmpl_parm) != TYPE_DECL
+ && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))
+ || (TREE_CODE (tmpl_parm) != PARM_DECL
+ && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (tmpl_parm))
+ != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm))))
+ || (TREE_CODE (tmpl_parm) == PARM_DECL
+ && (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (tmpl_parm))
+ != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))))))
{
error ("template parameter %q+#D", tmpl_parm);
error ("redeclared here as %q#D", parm);
template<template<typename> class...> struct A;
-template<template<typename...> class... B> struct A<B...> {}; // { dg-error "mismatch|'template<class ...> class B ...'" }
+template<template<typename...> class... B> struct A<B...> {}; // { dg-error "mismatch|'template<class ...> class ... B ...'" }
--- /dev/null
+// { dg-options "-std=c++0x" }
+
+template<typename Fun, typename... Args> // { dg-error "template parameter" }
+struct call;
+
+template<typename Fun, typename Arg0>
+struct call // { dg-error "redeclared here" }
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename X, typename Y>
+ struct result<X(Y)>
+ {
+ typedef X type;
+ };
+};
+
+
+template<typename Fun, int... N> // { dg-error "template parameter" }
+struct call2;
+
+template<typename Fun, int N>
+struct call2 // { dg-error "redeclared here" }
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename X, typename Y>
+ struct result<X(Y)>
+ {
+ typedef X type;
+ };
+};
+
+template<typename Fun, template<typename> class... TT> // { dg-error "template parameter" }
+struct call3;
+
+template<typename Fun, template<typename> class TT>
+struct call3 // { dg-error "redeclared here" }
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename X, typename Y>
+ struct result<X(Y)>
+ {
+ typedef X type;
+ };
+};