+1998-02-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2out.c: Add old_args_size.
+ (dwarf2out_args_size): Use it.
+ (dwarf2out_begin_prologue): Initialize it.
+ (dwarf2out_stack_adjust): If !asynchronous_exceptions, save up
+ pushed args until we see a call.
+ * final.c (final_scan_insn): Hand CALL_INSNs off to the dwarf2 code
+ before outputting them.
+
+1998-02-06 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * cplus-dem.c (demangle_template_template_parm): New function.
+ (demangle_template): Handle template template parameters.
+
1998-02-02 Mark Mitchell <mmitchell@usa.net>
* calls.c (expand_call): Don't confuse member functions named
demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
#endif
+static int
+demangle_template_template_parm PARAMS ((struct work_stuff *work,
+ const char **, string *));
+
static int
demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
string *, int));
#endif
+static int
+demangle_template_template_parm (work, mangled, tname)
+ struct work_stuff *work;
+ const char **mangled;
+ string *tname;
+{
+ int i;
+ int r;
+ int need_comma = 0;
+ int success = 1;
+ string temp;
+
+ string_append (tname, "template <");
+ /* get size of template parameter list */
+ if (get_count (mangled, &r))
+ {
+ for (i = 0; i < r; i++)
+ {
+ if (need_comma)
+ {
+ string_append (tname, ", ");
+ }
+
+ /* Z for type parameters */
+ if (**mangled == 'Z')
+ {
+ (*mangled)++;
+ string_append (tname, "class");
+ }
+ /* z for template parameters */
+ else if (**mangled == 'z')
+ {
+ (*mangled)++;
+ success =
+ demangle_template_template_parm (work, mangled, tname);
+ if (!success)
+ {
+ break;
+ }
+ }
+ else
+ {
+ /* temp is initialized in do_type */
+ success = do_type (work, mangled, &temp);
+ if (success)
+ {
+ string_appends (tname, &temp);
+ }
+ string_delete(&temp);
+ if (!success)
+ {
+ break;
+ }
+ }
+ need_comma = 1;
+ }
+
+ }
+ if (tname->p[-1] == '>')
+ string_append (tname, " ");
+ string_append (tname, "> class");
+ return (success);
+}
+
static int
demangle_template (work, mangled, tname, trawname, is_type)
struct work_stuff *work;
{
start = *mangled;
/* get template name */
- if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
+ if (**mangled == 'z')
{
- return (0);
+ int idx;
+ (*mangled)++;
+ (*mangled)++;
+
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1
+ || (work->tmpl_argvec && idx >= work->ntmpl_args)
+ || consume_count_with_underscores (mangled) == -1)
+ {
+ return (0);
+ }
+ if (work->tmpl_argvec)
+ {
+ string_append (tname, work->tmpl_argvec[idx]);
+ if (trawname)
+ string_append (trawname, work->tmpl_argvec[idx]);
+ }
+ else
+ {
+ char buf[10];
+ sprintf(buf, "T%d", idx);
+ string_append (tname, buf);
+ if (trawname)
+ string_append (trawname, work->tmpl_argvec[idx]);
+ }
}
- if (trawname)
- string_appendn (trawname, *mangled, r);
- is_java_array = (work -> options & DMGL_JAVA)
- && strncmp (*mangled, "JArray1Z", 8) == 0;
- if (! is_java_array)
+ else
{
- string_appendn (tname, *mangled, r);
+ if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
+ {
+ return (0);
+ }
+ if (trawname)
+ string_appendn (trawname, *mangled, r);
+ is_java_array = (work -> options & DMGL_JAVA)
+ && strncmp (*mangled, "JArray1Z", 8) == 0;
+ if (! is_java_array)
+ {
+ string_appendn (tname, *mangled, r);
+ }
+ *mangled += r;
}
- *mangled += r;
}
if (!is_java_array)
string_append (tname, "<");
break;
}
}
+ /* z for template parameters */
+ else if (**mangled == 'z')
+ {
+ int r2;
+ (*mangled)++;
+ success = demangle_template_template_parm (work, mangled, tname);
+
+ if (success
+ && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
+ {
+ string_append (tname, " ");
+ string_appendn (tname, *mangled, r2);
+ if (!is_type)
+ {
+ /* Save the template argument. */
+ int len = r2;
+ work->tmpl_argvec[i] = xmalloc (len + 1);
+ memcpy (work->tmpl_argvec[i], *mangled, len);
+ work->tmpl_argvec[i][len] = '\0';
+ }
+ *mangled += r2;
+ }
+ if (!success)
+ {
+ break;
+ }
+ }
else
{
string param;
/* The running total of the size of arguments pushed onto the stack. */
static long args_size;
+/* The last args_size we actually output. */
+static long old_args_size;
+
/* Entry point to update the canonical frame address (CFA).
LABEL is passed to add_fde_cfi. The value of CFA is now to be
calculated from REG+OFFSET. */
char *label;
long size;
{
- register dw_cfi_ref cfi = new_cfi ();
+ register dw_cfi_ref cfi;
+
+ if (size == old_args_size)
+ return;
+ old_args_size = size;
+
+ cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
add_fde_cfi (label, cfi);
long offset;
char *label;
+ if (! asynchronous_exceptions && GET_CODE (insn) == CALL_INSN)
+ {
+ /* Extract the size of the args from the CALL rtx itself. */
+
+ insn = PATTERN (insn);
+ if (GET_CODE (insn) == PARALLEL)
+ insn = XVECEXP (insn, 0, 0);
+ if (GET_CODE (insn) == SET)
+ insn = SET_SRC (insn);
+ assert (GET_CODE (insn) == CALL);
+ dwarf2out_args_size ("", INTVAL (XEXP (insn, 1)));
+ return;
+ }
+
+ /* If only calls can throw, and we have a frame pointer,
+ save up adjustments until we see the CALL_INSN. */
+ else if (! asynchronous_exceptions
+ && cfa_reg != STACK_POINTER_REGNUM)
+ return;
+
if (GET_CODE (insn) == BARRIER)
{
/* When we see a BARRIER, we know to reset args_size to 0. Usually
fde->dw_fde_end = NULL;
fde->dw_fde_cfi = NULL;
- args_size = 0;
+ args_size = old_args_size = 0;
}
/* Output a marker (i.e. a label) for the absolute end of the generated code
debug_insn = insn;
+#if defined (DWARF2_UNWIND_INFO) && !defined (ACCUMULATE_OUTGOING_ARGS)
+ /* If we push arguments, we want to know where the calls are. */
+ if (GET_CODE (insn) == CALL_INSN && dwarf2out_do_frame ())
+ dwarf2out_frame_debug (insn);
+#endif
+
/* If the proper template needs to be chosen by some C code,
run that code and get the real template. */
#if !defined (ACCUMULATE_OUTGOING_ARGS)
/* If we push arguments, we need to check all insns for stack
adjustments. */
- if (dwarf2out_do_frame ())
+ if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
#else
#if defined (HAVE_prologue)