aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/error.c67
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/error38.C19
6 files changed, 99 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 63d5c07..5cba9d0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2009-04-02 Jason Merrill <jason@redhat.com>
+
+ 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.
+
2009-04-02 Dodji Seketeli <dodji@redhat.com>
PR c++/26693
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f28cfc6..849fdc7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4593,6 +4593,7 @@ extern tree most_specialized_instantiation (tree);
extern void print_candidates (tree);
extern void instantiate_pending_templates (int);
extern tree tsubst_default_argument (tree, tree, tree);
+extern tree tsubst (tree, tree, tsubst_flags_t, tree);
extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t,
tree, bool, bool);
extern tree most_general_template (tree);
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);
}
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 58a4d3f..8b2fa6e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -170,7 +170,6 @@ static int eq_local_specializations (const void *, const void *);
static bool dependent_template_arg_p (tree);
static bool any_template_arguments_need_structural_equality_p (tree);
static bool dependent_type_p_r (tree);
-static tree tsubst (tree, tree, tsubst_flags_t, tree);
static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool);
static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
@@ -9079,7 +9078,7 @@ tsubst_exception_specification (tree fntype,
This function is used for dealing with types, decls and the like;
for expressions, use tsubst_expr or tsubst_copy. */
-static tree
+tree
tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree type, r;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8b5a1c3..4d1e325 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-04-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/25185
+ * g++.dg/template/error38.C: New test.
+
2009-04-02 Janis Johnson <janis187@us.ibm.com>
PR tree-optimization/31677
diff --git a/gcc/testsuite/g++.dg/template/error38.C b/gcc/testsuite/g++.dg/template/error38.C
new file mode 100644
index 0000000..a444b1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error38.C
@@ -0,0 +1,19 @@
+// Testcase for printing typename bindings as well as template args
+// in diagnostics (PR c++/25185)
+
+template <class T>
+struct A {
+ typename T::type f(); // { dg-message "typename T::type = void*" }
+ void f(int i = 0); // { dg-message "" }
+};
+
+struct B
+{
+ typedef void* type;
+};
+
+int main()
+{
+ A<B> a;
+ a.f(); // { dg-error "" }
+}