+1998-05-22 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (determine_specialization): Just return an error_mark_node.
+ Also print the decl we want in error messages. If we complain,
+ return error_mark_node.
+ (tsubst_friend_function): Set lineno and input_filename so
+ error messages will be useful.
+ (instantiate_template): Just return an error_mark_node.
+
+ * pt.c (print_template_context): Add new argument.
+ (maybe_print_template_context): New fn.
+ (push_tinst_level): Increment tinst_level_tick.
+ (pop_tinst_level): Likewise.
+ * errfn.c (cp_thing): Call maybe_print_template_context. Use
+ xrealloc instead of xmalloc.
+
+ * typeck.c (build_unary_op, CONVERT_EXPR): Propagate TREE_CONSTANT.
+
1998-05-21 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (tsubst_friend_class): Don't call redeclare_class_template
*targs_out = NULL_TREE;
+ if (fns == error_mark_node)
+ return error_mark_node;
+
/* Check for baselinks. */
if (TREE_CODE (fns) == TREE_LIST)
fns = TREE_VALUE (fns);
{
no_match:
if (complain)
- cp_error ("`%D' does not match any template declaration",
- template_id);
-
+ {
+ cp_error_at ("template-id `%D' for `%+D' does not match any template declaration",
+ template_id, decl);
+ return error_mark_node;
+ }
return NULL_TREE;
}
else if (TREE_CHAIN (templates) != NULL_TREE)
ambiguous:
if (complain)
{
- cp_error ("ambiguous template specialization `%D'",
- template_id);
+ cp_error_at ("ambiguous template specialization `%D' for `%+D'",
+ template_id, decl);
print_candidates (templates);
+ return error_mark_node;
}
return NULL_TREE;
}
return for_each_template_parm (t, 0, 0);
}
-static struct tinst_level *current_tinst_level = 0;
-static struct tinst_level *free_tinst_level = 0;
-static int tinst_depth = 0;
+static struct tinst_level *current_tinst_level;
+static struct tinst_level *free_tinst_level;
+static int tinst_depth;
extern int max_tinst_depth;
#ifdef GATHER_STATISTICS
-int depth_reached = 0;
+int depth_reached;
#endif
+int tinst_level_tick;
+int last_template_error_tick;
/* Print out all the template instantiations that we are currently
- working on. */
+ working on. If ERR, we are being called from cp_thing, so do
+ the right thing for an error message. */
-void
-print_template_context ()
+static void
+print_template_context (err)
+ int err;
{
struct tinst_level *p = current_tinst_level;
int line = lineno;
char *file = input_filename;
+ if (err)
+ {
+ if (current_function_decl == p->decl)
+ /* Avoid redundancy with the the "In function" line. */;
+ else if (current_function_decl == NULL_TREE)
+ cp_error ("In instantiation of `%D':", p->decl);
+ else
+ my_friendly_abort (980521);
+
+ if (p)
+ {
+ lineno = p->line;
+ input_filename = p->file;
+ p = p->next;
+ }
+ }
+
+ next:
for (; p; p = p->next)
{
cp_error (" instantiated from `%D'", p->decl);
input_filename = file;
}
+/* Called from cp_thing to print the template context for an error. */
+
+void
+maybe_print_template_context ()
+{
+ if (last_template_error_tick == tinst_level_tick
+ || current_tinst_level == 0)
+ return;
+
+ last_template_error_tick = tinst_level_tick;
+ print_template_context (1);
+}
+
static int
push_tinst_level (d)
tree d;
error (" (use -ftemplate-depth-NN to increase the maximum)");
cp_error (" instantiating `%D'", d);
- print_template_context ();
+ print_template_context (0);
return 0;
}
depth_reached = tinst_depth;
#endif
+ ++tinst_level_tick;
return 1;
}
old->next = free_tinst_level;
free_tinst_level = old;
--tinst_depth;
+ ++tinst_level_tick;
}
struct tinst_level *
tree args;
{
tree new_friend;
-
+ int line = lineno;
+ char *file = input_filename;
+
+ lineno = DECL_SOURCE_LINE (decl);
+ input_filename = DECL_SOURCE_FILE (decl);
+
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_TEMPLATE_INSTANTIATION (decl)
&& TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
new_friend,
&new_args,
0, 1);
- return instantiate_template (tmpl, new_args);
+ new_friend = instantiate_template (tmpl, new_args);
+ goto done;
}
- else
- new_friend = tsubst (decl, args, NULL_TREE);
+ else
+ new_friend = tsubst (decl, args, NULL_TREE);
/* The new_friend will look like an instantiation, to the
compiler, but is not an instantiation from the point of view of
new_friend = fn;
}
+ done:
+ lineno = line;
+ input_filename = file;
return new_friend;
}
struct obstack *old_fmp_obstack;
extern struct obstack *function_maybepermanent_obstack;
+ if (tmpl == error_mark_node)
+ return error_mark_node;
+
my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);
/* FIXME this won't work with member templates; we only have one level