aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/error.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-04-02 17:39:00 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-04-02 17:39:00 -0400
commitd5c8be275911317dc85c8441a852775c1192f022 (patch)
tree7cabe9179dbbf65afa81affa232feaffc076e6e0 /gcc/cp/error.c
parent14fdc6134e2a667f631cf91941402aaf09ffc24d (diff)
downloadgcc-d5c8be275911317dc85c8441a852775c1192f022.zip
gcc-d5c8be275911317dc85c8441a852775c1192f022.tar.gz
gcc-d5c8be275911317dc85c8441a852775c1192f022.tar.bz2
re PR c++/25185 (deep typedef substitution in error message)
PR c++/25185 * error.c (find_typenames, find_typenames_r): New fns. (dump_function_decl): Call find_typenames. (dump_template_bindings): Print typenames as well. * pt.c (tsubst): Non-static. * cp-tree.h: Declare it. From-SVN: r145476
Diffstat (limited to 'gcc/cp/error.c')
-rw-r--r--gcc/cp/error.c67
1 files changed, 64 insertions, 3 deletions
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 7d3756e..a3d6cc7 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "langhooks-def.h"
#include "cxx-pretty-print.h"
+#include "pointer-set.h"
#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
@@ -74,7 +75,7 @@ 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_parameter (tree, int);
-static void dump_template_bindings (tree, tree);
+static void dump_template_bindings (tree, tree, VEC(tree,gc) *);
static void dump_scope (tree, int);
static void dump_template_parms (tree, int, int);
@@ -227,9 +228,11 @@ dump_template_parameter (tree parm, int flags)
TREE_VEC. */
static void
-dump_template_bindings (tree parms, tree args)
+dump_template_bindings (tree parms, tree args, VEC(tree,gc)* typenames)
{
int need_comma = 0;
+ int i;
+ tree t;
while (parms)
{
@@ -267,6 +270,17 @@ dump_template_bindings (tree parms, tree args)
parms = TREE_CHAIN (parms);
}
+
+ for (i = 0; VEC_iterate (tree, typenames, i, t); ++i)
+ {
+ if (need_comma)
+ pp_separate_with_comma (cxx_pp);
+ dump_type (t, 0);
+ pp_cxx_whitespace (cxx_pp);
+ pp_equal (cxx_pp);
+ pp_cxx_whitespace (cxx_pp);
+ dump_type (tsubst (t, args, tf_none, NULL_TREE), 0);
+ }
}
/* Dump a human-readable equivalent of TYPE. FLAGS controls the
@@ -1074,6 +1088,51 @@ dump_template_decl (tree t, int flags)
}
}
+/* find_typenames looks through the type of the function template T
+ and returns a VEC containing any TYPENAME_TYPEs it finds. */
+
+struct find_typenames_t
+{
+ struct pointer_set_t *p_set;
+ VEC (tree,gc) *typenames;
+};
+
+static tree
+find_typenames_r (tree *tp, int *walk_subtrees, void *data)
+{
+ struct find_typenames_t *d = (struct find_typenames_t *)data;
+
+ if (TREE_CODE (*tp) == TYPENAME_TYPE)
+ {
+ /* Discard any cv-qualifiers. */
+ tree mv = TYPE_MAIN_VARIANT (*tp);
+ if (mv == *tp || !pointer_set_insert (d->p_set, mv))
+ VEC_safe_push (tree, gc, d->typenames, mv);
+ *walk_subtrees = 0;
+ }
+ /* Search into class template arguments, which cp_walk_subtrees
+ doesn't do. */
+ else if (CLASS_TYPE_P (*tp) && CLASSTYPE_TEMPLATE_INFO (*tp))
+ {
+ cp_walk_tree (&CLASSTYPE_TI_ARGS (*tp), find_typenames_r,
+ data, d->p_set);
+ *walk_subtrees = 0;
+ }
+ return NULL_TREE;
+}
+
+static VEC(tree,gc) *
+find_typenames (tree t)
+{
+ struct find_typenames_t ft;
+ ft.p_set = pointer_set_create ();
+ ft.typenames = NULL;
+ cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
+ find_typenames_r, &ft, ft.p_set);
+ pointer_set_destroy (ft.p_set);
+ return ft.typenames;
+}
+
/* Pretty print a function decl. There are several ways we want to print a
function declaration. The TFF_ bits in FLAGS tells us how to behave.
As error can only apply the '#' flag once to give 0 and 1 for V, there
@@ -1090,6 +1149,7 @@ dump_function_decl (tree t, int flags)
int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
tree exceptions;
+ VEC(tree,gc) *typenames = NULL;
flags &= ~TFF_UNQUALIFIED_NAME;
if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -1110,6 +1170,7 @@ dump_function_decl (tree t, int flags)
{
template_parms = DECL_TEMPLATE_PARMS (tmpl);
t = tmpl;
+ typenames = find_typenames (t);
}
}
@@ -1177,7 +1238,7 @@ dump_function_decl (tree t, int flags)
pp_cxx_left_bracket (cxx_pp);
pp_cxx_identifier (cxx_pp, "with");
pp_cxx_whitespace (cxx_pp);
- dump_template_bindings (template_parms, template_args);
+ dump_template_bindings (template_parms, template_args, typenames);
pp_cxx_right_bracket (cxx_pp);
}
}