static void dump_parameters (tree, int);
static void dump_exception_spec (tree, int);
static void dump_template_argument (tree, int);
-static void dump_template_argument_list (tree, int);
+static void dump_template_argument_list (tree, tree, int);
static void dump_template_parameter (tree, int);
static void dump_template_bindings (tree, tree, VEC(tree,gc) *);
static void dump_scope (tree, int);
static void dump_template_parms (tree, int, int);
+static int count_non_default_template_args (tree, tree);
+
static const char *function_category (tree);
static void maybe_print_instantiation_context (diagnostic_context *);
static void print_instantiation_full_context (diagnostic_context *);
dump_template_argument (tree arg, int flags)
{
if (ARGUMENT_PACK_P (arg))
- dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), flags);
+ dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), NULL_TREE, flags);
else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
else
}
}
+/* Count the number of template arguments ARGS whose value does not
+ match the (optional) default template parameter in PARAMS */
+
+static int
+count_non_default_template_args (tree args, tree params)
+{
+ int n = TREE_VEC_LENGTH (args);
+ int last;
+
+ if (params == NULL_TREE)
+ return n;
+
+ for (last = n - 1; last >= 0; --last)
+ {
+ tree param = TREE_VEC_ELT (params, last);
+ tree def = TREE_PURPOSE (param);
+
+ if (!def)
+ break;
+ if (uses_template_parms (def))
+ {
+ ++processing_template_decl;
+ def = tsubst_copy_and_build (def, args, tf_none, NULL_TREE, false, true);
+ --processing_template_decl;
+ }
+ if (!cp_tree_equal (TREE_VEC_ELT (args, last), def))
+ break;
+ }
+
+ return last + 1;
+}
+
/* Dump a template-argument-list ARGS (always a TREE_VEC) under control
of FLAGS. */
static void
-dump_template_argument_list (tree args, int flags)
+dump_template_argument_list (tree args, tree parms, int flags)
{
- int n = TREE_VEC_LENGTH (args);
+ int n = count_non_default_template_args (args, parms);
int need_comma = 0;
int i;
- for (i = 0; i< n; ++i)
+ for (i = 0; i < n; ++i)
{
tree arg = TREE_VEC_ELT (args, i);
int lvl = TMPL_PARMS_DEPTH (parms);
int arg_idx = 0;
int i;
+ tree lvl_args = NULL_TREE;
+
+ /* Don't crash if we had an invalid argument list. */
+ if (TMPL_ARGS_DEPTH (args) >= lvl)
+ lvl_args = TMPL_ARGS_LEVEL (args, lvl);
for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
{
tree arg = NULL_TREE;
/* Don't crash if we had an invalid argument list. */
- if (TMPL_ARGS_DEPTH (args) >= lvl)
- {
- tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
- if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
- arg = TREE_VEC_ELT (lvl_args, arg_idx);
- }
+ if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
+ arg = TREE_VEC_ELT (lvl_args, arg_idx);
if (need_comma)
pp_separate_with_comma (cxx_pp);
pp_cxx_cv_qualifier_seq (cxx_pp, t);
pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
pp_cxx_begin_template_argument_list (cxx_pp);
- dump_template_argument_list (args, flags);
+ dump_template_argument_list (args, NULL_TREE, flags);
pp_cxx_end_template_argument_list (cxx_pp);
}
break;
dump_decl (name, flags);
pp_cxx_begin_template_argument_list (cxx_pp);
if (TREE_OPERAND (t, 1))
- dump_template_argument_list (TREE_OPERAND (t, 1), flags);
+ dump_template_argument_list (TREE_OPERAND (t, 1), NULL_TREE, flags);
pp_cxx_end_template_argument_list (cxx_pp);
}
break;
if (args && !primary)
{
int len, ix;
+ /* We don't know the parms for a friend template specialization. */
+ tree params = (TREE_CODE (TI_TEMPLATE (info)) == TEMPLATE_DECL
+ ? DECL_INNERMOST_TEMPLATE_PARMS (TI_TEMPLATE (info))
+ : NULL_TREE);
if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
- len = TREE_VEC_LENGTH (args);
+ len = count_non_default_template_args (args, params);
for (ix = 0; ix != len; ix++)
{