* debug.h (struct debug_write_fns): Remove ellipsis_type. Add int

and boolean parameters to function_type.  Add boolean parameter to
	method_type.
	(debug_make_ellipsis_type): Don't declare.
	(debug_make_function_type): Add debug_type * and boolean
	parameters.  Change all callers.
	(debug_make_method_type): Add boolean parameter.  Change all
	callers.
	(debug_get_parameter_types): Add boolean * parameter.  Change all
	callers.
	(debug_get_target_type): Declare.
	* debug.c (struct debug_function_type): Add fields arg_types and
	varargs.
	(struct debug_method_type): Add field varargs.
	(debug_ellipsis_type, ELLIPSIS_P): Remove.
	(debug_make_ellipsis_type): Remove.
	(debug_make_function_type): Add arg_types and varargs parameters.
	(debug_make_method_type): Add varargs parameter.
	(debug_get_parameter_types): Add pvarargs parameter.
	(debug_get_target_type): New function.
	(debug_write_type): In case DEBUG_KIND_FUNCTION, push argument
	types and pass count to function_type.  In DEBUG_KIND_METHOD, use
	a signed int for the count, don't call ellipsis_type, and pass
	varargs to method_type.
	* stabs.c (struct stab_demangle_info): Add varargs field.
	(stab_demangle_argtypes): Add pvarargs parameter.  Change all
	callers.
	(stab_demangle_args): Likewise.
	(stab_demangle_type): In case 'F', pick up argument types.
	* prdbg.c (pr_ellipsis_type): Remove.
	(pr_function_type): Add argcount and varargs parameters.
	(pr_method_type): Add varargs parameter.
	* ieee.c (ieee_ellipsis_type): Remove.
	(ieee_function_type): Add argcount and varargs parameters.
	(ieee_method_type): Add varargs parameter.  Remove most of
	function body, and just call ieee_function_type.
This commit is contained in:
Ian Lance Taylor 1996-01-19 19:44:00 +00:00
parent d3023c8f19
commit 267e52989e
5 changed files with 316 additions and 215 deletions

View file

@ -1,5 +1,42 @@
Fri Jan 19 12:31:57 1996 Ian Lance Taylor <ian@cygnus.com> Fri Jan 19 12:31:57 1996 Ian Lance Taylor <ian@cygnus.com>
* debug.h (struct debug_write_fns): Remove ellipsis_type. Add int
and boolean parameters to function_type. Add boolean parameter to
method_type.
(debug_make_ellipsis_type): Don't declare.
(debug_make_function_type): Add debug_type * and boolean
parameters. Change all callers.
(debug_make_method_type): Add boolean parameter. Change all
callers.
(debug_get_parameter_types): Add boolean * parameter. Change all
callers.
(debug_get_target_type): Declare.
* debug.c (struct debug_function_type): Add fields arg_types and
varargs.
(struct debug_method_type): Add field varargs.
(debug_ellipsis_type, ELLIPSIS_P): Remove.
(debug_make_ellipsis_type): Remove.
(debug_make_function_type): Add arg_types and varargs parameters.
(debug_make_method_type): Add varargs parameter.
(debug_get_parameter_types): Add pvarargs parameter.
(debug_get_target_type): New function.
(debug_write_type): In case DEBUG_KIND_FUNCTION, push argument
types and pass count to function_type. In DEBUG_KIND_METHOD, use
a signed int for the count, don't call ellipsis_type, and pass
varargs to method_type.
* stabs.c (struct stab_demangle_info): Add varargs field.
(stab_demangle_argtypes): Add pvarargs parameter. Change all
callers.
(stab_demangle_args): Likewise.
(stab_demangle_type): In case 'F', pick up argument types.
* prdbg.c (pr_ellipsis_type): Remove.
(pr_function_type): Add argcount and varargs parameters.
(pr_method_type): Add varargs parameter.
* ieee.c (ieee_ellipsis_type): Remove.
(ieee_function_type): Add argcount and varargs parameters.
(ieee_method_type): Add varargs parameter. Remove most of
function body, and just call ieee_function_type.
* stabs.c: Include "demangle.h". Added several new static * stabs.c: Include "demangle.h". Added several new static
functions not listed below to demangle argument types; they are functions not listed below to demangle argument types; they are
all called via stab_demangle_argtypes. all called via stab_demangle_argtypes.

View file

@ -184,6 +184,10 @@ struct debug_function_type
{ {
/* Return type. */ /* Return type. */
debug_type return_type; debug_type return_type;
/* NULL terminated array of argument types. */
debug_type *arg_types;
/* Whether the function takes a variable number of arguments. */
boolean varargs;
}; };
/* Information kept for a range. */ /* Information kept for a range. */
@ -244,6 +248,8 @@ struct debug_method_type
debug_type domain_type; debug_type domain_type;
/* A NULL terminated array of argument types. */ /* A NULL terminated array of argument types. */
debug_type *arg_types; debug_type *arg_types;
/* Whether the method takes a variable number of arguments. */
boolean varargs;
}; };
/* Information kept for a named type. */ /* Information kept for a named type. */
@ -503,15 +509,6 @@ struct debug_name
} u; } u;
}; };
/* This variable is an ellipsis type. The contents are not used; its
address is returned by debug_make_ellipsis_type, and anything which
needs to know whether it is dealing with an ellipsis compares
addresses. */
static const struct debug_type debug_ellipsis_type;
#define ELLIPSIS_P(t) ((t) == &debug_ellipsis_type)
/* Local functions. */ /* Local functions. */
static void debug_error PARAMS ((const char *)); static void debug_error PARAMS ((const char *));
@ -1241,18 +1238,6 @@ debug_make_indirect_type (handle, slot, tag)
return t; return t;
} }
/* Make an ellipsis type. This is not a type at all, but is a marker
suitable for appearing in the list of argument types passed to
debug_make_method_type. It should be used to indicate a method
which takes a variable number of arguments. */
debug_type
debug_make_ellipsis_type (handle)
PTR handle;
{
return (debug_type) &debug_ellipsis_type;
}
/* Make a void type. There is only one of these. */ /* Make a void type. There is only one of these. */
debug_type debug_type
@ -1458,9 +1443,11 @@ debug_make_pointer_type (handle, type)
to record the parameter types. */ to record the parameter types. */
debug_type debug_type
debug_make_function_type (handle, type) debug_make_function_type (handle, type, arg_types, varargs)
PTR handle; PTR handle;
debug_type type; debug_type type;
debug_type *arg_types;
boolean varargs;
{ {
struct debug_handle *info = (struct debug_handle *) handle; struct debug_handle *info = (struct debug_handle *) handle;
struct debug_type *t; struct debug_type *t;
@ -1477,6 +1464,8 @@ debug_make_function_type (handle, type)
memset (f, 0, sizeof *f); memset (f, 0, sizeof *f);
f->return_type = type; f->return_type = type;
f->arg_types = arg_types;
f->varargs = varargs;
t->u.kfunction = f; t->u.kfunction = f;
@ -1648,11 +1637,12 @@ debug_make_offset_type (handle, base_type, target_type)
argument is a NULL terminated array of argument types. */ argument is a NULL terminated array of argument types. */
debug_type debug_type
debug_make_method_type (handle, return_type, domain_type, arg_types) debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
PTR handle; PTR handle;
debug_type return_type; debug_type return_type;
debug_type domain_type; debug_type domain_type;
debug_type *arg_types; debug_type *arg_types;
boolean varargs;
{ {
struct debug_handle *info = (struct debug_handle *) handle; struct debug_handle *info = (struct debug_handle *) handle;
struct debug_type *t; struct debug_type *t;
@ -1671,6 +1661,7 @@ debug_make_method_type (handle, return_type, domain_type, arg_types)
m->return_type = return_type; m->return_type = return_type;
m->domain_type = domain_type; m->domain_type = domain_type;
m->arg_types = arg_types; m->arg_types = arg_types;
m->varargs = varargs;
t->u.kmethod = m; t->u.kmethod = m;
@ -2230,7 +2221,29 @@ debug_get_return_type (handle, type)
we don't currently store the parameter types of a function). */ we don't currently store the parameter types of a function). */
const debug_type * const debug_type *
debug_get_parameter_types (handle, type) debug_get_parameter_types (handle, type, pvarargs)
PTR handle;
debug_type type;
boolean *pvarargs;
{
if (type == NULL)
return NULL;
type = debug_get_real_type (handle, type);
switch (type->kind)
{
default:
return NULL;
case DEBUG_KIND_METHOD:
*pvarargs = type->u.kmethod->varargs;
return type->u.kmethod->arg_types;
}
/*NOTREACHED*/
}
/* Get the target type of a type. */
debug_type
debug_get_target_type (handle, type)
PTR handle; PTR handle;
debug_type type; debug_type type;
{ {
@ -2241,8 +2254,14 @@ debug_get_parameter_types (handle, type)
{ {
default: default:
return NULL; return NULL;
case DEBUG_KIND_METHOD: case DEBUG_KIND_POINTER:
return type->u.kmethod->arg_types; return type->u.kpointer;
case DEBUG_KIND_REFERENCE:
return type->u.kreference;
case DEBUG_KIND_CONST:
return type->u.kconst;
case DEBUG_KIND_VOLATILE:
return type->u.kvolatile;
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }
@ -2422,6 +2441,7 @@ debug_write_type (info, fns, fhandle, type, name)
struct debug_name *name; struct debug_name *name;
{ {
unsigned int i; unsigned int i;
int is;
const char *tag; const char *tag;
/* If we have a name for this type, just output it. We only output /* If we have a name for this type, just output it. We only output
@ -2533,11 +2553,22 @@ debug_write_type (info, fns, fhandle, type, name)
return false; return false;
return (*fns->pointer_type) (fhandle); return (*fns->pointer_type) (fhandle);
case DEBUG_KIND_FUNCTION: case DEBUG_KIND_FUNCTION:
if (type->u.kfunction->arg_types == NULL)
is = -1;
else
{
for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
if (! debug_write_type (info, fns, fhandle,
type->u.kfunction->arg_types[is],
(struct debug_name *) NULL))
return false;
}
if (! debug_write_type (info, fns, fhandle, if (! debug_write_type (info, fns, fhandle,
type->u.kfunction->return_type, type->u.kfunction->return_type,
(struct debug_name *) NULL)) (struct debug_name *) NULL))
return false; return false;
return (*fns->function_type) (fhandle); return (*fns->function_type) (fhandle, is,
type->u.kfunction->varargs);
case DEBUG_KIND_REFERENCE: case DEBUG_KIND_REFERENCE:
if (! debug_write_type (info, fns, fhandle, type->u.kreference, if (! debug_write_type (info, fns, fhandle, type->u.kreference,
(struct debug_name *) NULL)) (struct debug_name *) NULL))
@ -2578,24 +2609,14 @@ debug_write_type (info, fns, fhandle, type, name)
(struct debug_name *) NULL)) (struct debug_name *) NULL))
return false; return false;
if (type->u.kmethod->arg_types == NULL) if (type->u.kmethod->arg_types == NULL)
i = -1; is = -1;
else else
{ {
for (i = 0; type->u.kmethod->arg_types[i] != NULL; i++) for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
{ if (! debug_write_type (info, fns, fhandle,
if (ELLIPSIS_P (type->u.kmethod->arg_types[i])) type->u.kmethod->arg_types[is],
{ (struct debug_name *) NULL))
if (! (*fns->ellipsis_type) (fhandle)) return false;
return false;
}
else
{
if (! debug_write_type (info, fns, fhandle,
type->u.kmethod->arg_types[i],
(struct debug_name *) NULL))
return false;
}
}
} }
if (type->u.kmethod->domain_type != NULL) if (type->u.kmethod->domain_type != NULL)
{ {
@ -2606,7 +2627,8 @@ debug_write_type (info, fns, fhandle, type, name)
} }
return (*fns->method_type) (fhandle, return (*fns->method_type) (fhandle,
type->u.kmethod->domain_type != NULL, type->u.kmethod->domain_type != NULL,
i); is,
type->u.kmethod->varargs);
case DEBUG_KIND_CONST: case DEBUG_KIND_CONST:
if (! debug_write_type (info, fns, fhandle, type->u.kconst, if (! debug_write_type (info, fns, fhandle, type->u.kconst,
(struct debug_name *) NULL)) (struct debug_name *) NULL))

View file

@ -174,11 +174,6 @@ struct debug_write_fns
/* Each writer must keep a stack of types. */ /* Each writer must keep a stack of types. */
/* Push an ellipsis type onto the type stack. This is not a real
type, but is used when a method takes a variable number of
arguments. */
boolean (*ellipsis_type) PARAMS ((PTR));
/* Push an empty type onto the type stack. This type can appear if /* Push an empty type onto the type stack. This type can appear if
there is a reference to a type which is never defined. */ there is a reference to a type which is never defined. */
boolean (*empty_type) PARAMS ((PTR)); boolean (*empty_type) PARAMS ((PTR));
@ -210,9 +205,15 @@ struct debug_write_fns
type onto the type stack. */ type onto the type stack. */
boolean (*pointer_type) PARAMS ((PTR)); boolean (*pointer_type) PARAMS ((PTR));
/* Pop the top type on the type stack, and push a function returning /* Push a function type onto the type stack. The second argument
that type onto the type stack. */ indicates the number of argument types that have been pushed onto
boolean (*function_type) PARAMS ((PTR)); the stack. If the number of argument types is passed as -1, then
the argument types of the function are unknown, and no types have
been pushed onto the stack. The third argument is true if the
function takes a variable number of arguments. The return type
of the function is pushed onto the type stack below the argument
types, if any. */
boolean (*function_type) PARAMS ((PTR, int, boolean));
/* Pop the top type on the type stack, and push a reference to that /* Pop the top type on the type stack, and push a reference to that
type onto the type stack. */ type onto the type stack. */
@ -247,12 +248,13 @@ struct debug_write_fns
class to which the method is attached. The third argument is the class to which the method is attached. The third argument is the
number of argument types; these are pushed onto the type stack in number of argument types; these are pushed onto the type stack in
reverse order (the first type popped is the last argument to the reverse order (the first type popped is the last argument to the
method). An argument type of -1 means that no argument in method). A value of -1 for the third argument means that no
formation is available. The next type on the type stack below argument information is available. The fourth argument is true
the domain and the argument types is the return type of the if the function takes a variable number of arguments. The next
method. All these types must be popped, and then the method type type on the type stack below the domain and the argument types is
must be pushed. */ the return type of the method. All these types must be popped,
boolean (*method_type) PARAMS ((PTR, boolean, int)); and then the method type must be pushed. */
boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
/* Pop the top type off the type stack, and push a const qualified /* Pop the top type off the type stack, and push a const qualified
version of that type onto the type stack. */ version of that type onto the type stack. */
@ -519,13 +521,6 @@ extern boolean debug_record_variable
extern debug_type debug_make_indirect_type extern debug_type debug_make_indirect_type
PARAMS ((PTR, debug_type *, const char *)); PARAMS ((PTR, debug_type *, const char *));
/* Make an ellipsis type. This is not a type at all, but is a marker
suitable for appearing in the list of argument types passed to
debug_make_method_type. It should be used to indicate a method
which takes a variable number of arguments. */
extern debug_type debug_make_ellipsis_type PARAMS ((PTR));
/* Make a void type. */ /* Make a void type. */
extern debug_type debug_make_void_type PARAMS ((PTR)); extern debug_type debug_make_void_type PARAMS ((PTR));
@ -578,10 +573,14 @@ extern debug_type debug_make_enum_type
extern debug_type debug_make_pointer_type extern debug_type debug_make_pointer_type
PARAMS ((PTR, debug_type)); PARAMS ((PTR, debug_type));
/* Make a function returning a given type. FIXME: We should be able /* Make a function type. The second argument is the return type. The
to record the parameter types. */ third argument is a NULL terminated array of argument types. The
fourth argument is true if the function takes a variable number of
arguments. If the third argument is NULL, then the argument types
are unknown. */
extern debug_type debug_make_function_type PARAMS ((PTR, debug_type)); extern debug_type debug_make_function_type
PARAMS ((PTR, debug_type, debug_type *, boolean));
/* Make a reference to a given type. */ /* Make a reference to a given type. */
@ -618,14 +617,17 @@ extern debug_type debug_make_offset_type
PARAMS ((PTR, debug_type, debug_type)); PARAMS ((PTR, debug_type, debug_type));
/* Make a type for a method function. The second argument is the /* Make a type for a method function. The second argument is the
return type, the third argument is the domain, and the fourth return type. The third argument is the domain. The fourth
argument is a NULL terminated array of argument types. The domain argument is a NULL terminated array of argument types. The fifth
and the argument array may be NULL, in which case this is a stub argument is true if the function takes a variable number of
method and that information is not available. Stabs debugging uses arguments, in which case the array of argument types indicates the
this, and gets the argument types from the mangled name. */ types of the first arguments. The domain and the argument array
may be NULL, in which case this is a stub method and that
information is not available. Stabs debugging uses this, and gets
the argument types from the mangled name. */
extern debug_type debug_make_method_type extern debug_type debug_make_method_type
PARAMS ((PTR, debug_type, debug_type, debug_type *)); PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
/* Make a const qualified version of a given type. */ /* Make a const qualified version of a given type. */
@ -738,9 +740,18 @@ extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
/* Get the NULL terminated array of parameter types for a function or /* Get the NULL terminated array of parameter types for a function or
method type (actually, parameter types are not currently stored for method type (actually, parameter types are not currently stored for
function types). This may be used to determine whether a method function types). This may be used to determine whether a method
type is a stub method or not. */ type is a stub method or not. The last argument points to a
boolean which is set to true if the function takes a variable
number of arguments. */
extern const debug_type *debug_get_parameter_types PARAMS ((PTR, debug_type)); extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
debug_type,
boolean *));
/* Get the target type of a pointer or reference or const or volatile
type. */
extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
/* Get the NULL terminated array of fields for a struct, union, or /* Get the NULL terminated array of fields for a struct, union, or
class. */ class. */

View file

@ -1664,7 +1664,8 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
} }
while (present); while (present);
type = debug_make_function_type (dhandle, rtype); type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
false);
return_type = rtype; return_type = rtype;
} }
break; break;
@ -1779,6 +1780,8 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
{ {
bfd_vma attr, frame_type, push_mask, nargs, level, father; bfd_vma attr, frame_type, push_mask, nargs, level, father;
debug_type rtype; debug_type rtype;
debug_type *arg_types;
boolean varargs;
boolean present; boolean present;
/* FIXME: We ignore almost all this information. */ /* FIXME: We ignore almost all this information. */
@ -1790,23 +1793,49 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
&rtype) &rtype)
|| ! ieee_read_number (abfd, bytes, pp, pend, &nargs)) || ! ieee_read_number (abfd, bytes, pp, pend, &nargs))
return false; return false;
if (nargs != (bfd_vma) -1) if (nargs == (bfd_vma) -1)
{ {
for (; nargs > 0; nargs--) arg_types = NULL;
{ varargs = false;
debug_type atype; }
else
{
unsigned int i;
if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp, arg_types = ((debug_type *)
pend, &atype)) xmalloc ((nargs + 1) * sizeof *arg_types));
return false; for (i = 0; i < nargs; i++)
if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp,
pend, arg_types + i))
return false;
/* If the last type is pointer to void, this is really a
varargs function. */
varargs = false;
if (nargs > 0)
{
debug_type last;
last = arg_types[nargs - 1];
if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
&& (debug_get_type_kind (dhandle,
debug_get_target_type (dhandle,
last))
== DEBUG_KIND_VOID))
{
--nargs;
varargs = true;
}
} }
arg_types[nargs] = DEBUG_TYPE_NULL;
} }
if (! ieee_read_number (abfd, bytes, pp, pend, &level) if (! ieee_read_number (abfd, bytes, pp, pend, &level)
|| ! ieee_read_optional_number (abfd, bytes, pp, pend, &father, || ! ieee_read_optional_number (abfd, bytes, pp, pend, &father,
&present)) &present))
return false; return false;
type = debug_make_function_type (dhandle, rtype); type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
return_type = rtype; return_type = rtype;
} }
break; break;
@ -2357,7 +2386,6 @@ static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *)); static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
static boolean ieee_start_source PARAMS ((PTR, const char *)); static boolean ieee_start_source PARAMS ((PTR, const char *));
static boolean ieee_ellipsis_type PARAMS ((PTR));
static boolean ieee_empty_type PARAMS ((PTR)); static boolean ieee_empty_type PARAMS ((PTR));
static boolean ieee_void_type PARAMS ((PTR)); static boolean ieee_void_type PARAMS ((PTR));
static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean)); static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
@ -2367,14 +2395,14 @@ static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
static boolean ieee_enum_type static boolean ieee_enum_type
PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
static boolean ieee_pointer_type PARAMS ((PTR)); static boolean ieee_pointer_type PARAMS ((PTR));
static boolean ieee_function_type PARAMS ((PTR)); static boolean ieee_function_type PARAMS ((PTR, int, boolean));
static boolean ieee_reference_type PARAMS ((PTR)); static boolean ieee_reference_type PARAMS ((PTR));
static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
static boolean ieee_array_type static boolean ieee_array_type
PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
static boolean ieee_set_type PARAMS ((PTR, boolean)); static boolean ieee_set_type PARAMS ((PTR, boolean));
static boolean ieee_offset_type PARAMS ((PTR)); static boolean ieee_offset_type PARAMS ((PTR));
static boolean ieee_method_type PARAMS ((PTR, boolean, int)); static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
static boolean ieee_const_type PARAMS ((PTR)); static boolean ieee_const_type PARAMS ((PTR));
static boolean ieee_volatile_type PARAMS ((PTR)); static boolean ieee_volatile_type PARAMS ((PTR));
static boolean ieee_start_struct_type static boolean ieee_start_struct_type
@ -2420,7 +2448,6 @@ static const struct debug_write_fns ieee_fns =
{ {
ieee_start_compilation_unit, ieee_start_compilation_unit,
ieee_start_source, ieee_start_source,
ieee_ellipsis_type,
ieee_empty_type, ieee_empty_type,
ieee_void_type, ieee_void_type,
ieee_int_type, ieee_int_type,
@ -3161,15 +3188,6 @@ ieee_start_source (p, filename)
return true; return true;
} }
/* Make an ellipsis type. */
static boolean
ieee_ellipsis_type (p)
PTR p;
{
abort ();
}
/* Make an empty type. */ /* Make an empty type. */
static boolean static boolean
@ -3382,27 +3400,53 @@ ieee_pointer_type (p)
/* Make a function type. */ /* Make a function type. */
static boolean static boolean
ieee_function_type (p) ieee_function_type (p, argcount, varargs)
PTR p; PTR p;
int argcount;
boolean varargs;
{ {
struct ieee_handle *info = (struct ieee_handle *) p; struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int indx; unsigned int *args = NULL;
int i;
unsigned int retindx;
indx = ieee_pop_type (info); if (argcount > 0)
{
args = (unsigned int *) xmalloc (argcount * sizeof *args);
for (i = argcount - 1; i >= 0; i--)
args[i] = ieee_pop_type (info);
}
else if (argcount < 0)
varargs = false;
/* FIXME: IEEE can represent the argument types for the function, retindx = ieee_pop_type (info);
but we didn't store them. */
/* An attribute of 0x41 means that the frame and push mask are /* An attribute of 0x41 means that the frame and push mask are
unknown. */ unknown. */
return (ieee_define_type (info, 0, true) if (! ieee_define_type (info, 0, true)
&& ieee_write_number (info, 'x') || ! ieee_write_number (info, 'x')
&& ieee_write_number (info, 0x41) || ! ieee_write_number (info, 0x41)
&& ieee_write_number (info, 0) || ! ieee_write_number (info, 0)
&& ieee_write_number (info, 0) || ! ieee_write_number (info, 0)
&& ieee_write_number (info, indx) || ! ieee_write_number (info, retindx)
&& ieee_write_number (info, (bfd_vma) -1) || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
&& ieee_write_number (info, 0)); return false;
if (argcount > 0)
{
for (i = 0; i < argcount; i++)
if (! ieee_write_number (info, args[i]))
return false;
free (args);
}
if (varargs)
{
/* A varargs function is represented by writing out the last
argument as type void *, although this makes little sense. */
if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
return false;
}
return ieee_write_number (info, 0);
} }
/* Make a reference type. */ /* Make a reference type. */
@ -3520,15 +3564,13 @@ ieee_offset_type (p)
/* Make a method type. */ /* Make a method type. */
static boolean static boolean
ieee_method_type (p, domain, argcount) ieee_method_type (p, domain, argcount, varargs)
PTR p; PTR p;
boolean domain; boolean domain;
int argcount; int argcount;
boolean varargs;
{ {
struct ieee_handle *info = (struct ieee_handle *) p; struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int *args = NULL;
int i;
unsigned int retindx;
/* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
method, but the definition is incomplete. We just output an 'x' method, but the definition is incomplete. We just output an 'x'
@ -3537,32 +3579,7 @@ ieee_method_type (p, domain, argcount)
if (domain) if (domain)
(void) ieee_pop_type (info); (void) ieee_pop_type (info);
if (argcount > 0) return ieee_function_type (p, argcount, varargs);
{
args = (unsigned int *) xmalloc (argcount * sizeof *args);
for (i = argcount - 1; i >= 0; i--)
args[i] = ieee_pop_type (info);
}
retindx = ieee_pop_type (info);
if (! ieee_define_type (info, 0, true)
|| ! ieee_write_number (info, 'x')
|| ! ieee_write_number (info, 0x41)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, retindx)
|| ! ieee_write_number (info, (bfd_vma) argcount))
return false;
if (argcount > 0)
{
for (i = 0; i < argcount; i++)
if (! ieee_write_number (info, args[i]))
return false;
free (args);
}
return ieee_write_number (info, 0);
} }
/* Make a const qualified type. */ /* Make a const qualified type. */

View file

@ -193,7 +193,7 @@ static debug_type stab_find_tagged_type
PARAMS ((PTR, struct stab_handle *, const char *, int, PARAMS ((PTR, struct stab_handle *, const char *, int,
enum debug_type_kind)); enum debug_type_kind));
static debug_type *stab_demangle_argtypes static debug_type *stab_demangle_argtypes
PARAMS ((PTR, struct stab_handle *, const char *)); PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
/* Save a string in memory. */ /* Save a string in memory. */
@ -827,9 +827,13 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
(debug_type **) NULL); (debug_type **) NULL);
if (dtype != DEBUG_TYPE_NULL) if (dtype != DEBUG_TYPE_NULL)
dtype = debug_make_pointer_type (dhandle, {
debug_make_function_type (dhandle, debug_type ftype;
dtype));
ftype = debug_make_function_type (dhandle, dtype,
(debug_type *) NULL, false);
dtype = debug_make_pointer_type (dhandle, ftype);
}
} }
if (dtype == DEBUG_TYPE_NULL) if (dtype == DEBUG_TYPE_NULL)
return false; return false;
@ -1278,7 +1282,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
dtype = (debug_make_function_type dtype = (debug_make_function_type
(dhandle, (dhandle,
parse_stab_type (dhandle, info, (const char *) NULL, pp, parse_stab_type (dhandle, info, (const char *) NULL, pp,
(debug_type **) NULL))); (debug_type **) NULL),
(debug_type *) NULL, false));
break; break;
case 'k': case 'k':
@ -1348,7 +1353,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
} }
++*pp; ++*pp;
dtype = debug_make_method_type (dhandle, return_type, dtype = debug_make_method_type (dhandle, return_type,
DEBUG_TYPE_NULL, NULL); DEBUG_TYPE_NULL,
(debug_type *) NULL, false);
} }
else else
{ {
@ -1357,6 +1363,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
debug_type *args; debug_type *args;
unsigned int n; unsigned int n;
unsigned int alloc; unsigned int alloc;
boolean varargs;
domain = parse_stab_type (dhandle, info, (const char *) NULL, domain = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL); pp, (debug_type **) NULL);
@ -1402,30 +1409,22 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
} }
++*pp; ++*pp;
/* If the last type is void, then this function does not /* If the last type is not void, then this function takes a
take a variable number of arguments. If the last is not variable number of arguments. Otherwise, we must strip
void, then it does. */ the void type. */
if (n > 0 if (n == 0
&& debug_get_type_kind (dhandle, args[n - 1]) == DEBUG_KIND_VOID) || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
--n; varargs = true;
else else
{ {
if (n + 1 >= alloc) --n;
{ varargs = false;
alloc += 10;
args = ((debug_type *)
xrealloc ((PTR) args, alloc * sizeof *args));
}
args[n] = debug_make_ellipsis_type (dhandle);
if (args[n] == DEBUG_TYPE_NULL)
return DEBUG_TYPE_NULL;
++n;
} }
args[n] = DEBUG_TYPE_NULL; args[n] = DEBUG_TYPE_NULL;
dtype = debug_make_method_type (dhandle, return_type, domain, args); dtype = debug_make_method_type (dhandle, return_type, domain, args,
varargs);
} }
break; break;
@ -2499,6 +2498,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
bfd_vma voffset; bfd_vma voffset;
debug_type context; debug_type context;
const char *physname; const char *physname;
boolean varargs;
if (look_ahead_type != DEBUG_TYPE_NULL) if (look_ahead_type != DEBUG_TYPE_NULL)
{ {
@ -2661,7 +2661,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
and the argument types, must be deduced from it. */ and the argument types, must be deduced from it. */
if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
&& debug_get_parameter_types (dhandle, type) != NULL) && debug_get_parameter_types (dhandle, type, &varargs) != NULL)
physname = argtypes; physname = argtypes;
else else
{ {
@ -2759,6 +2759,7 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
boolean is_constructor; boolean is_constructor;
boolean is_destructor; boolean is_destructor;
debug_type *args; debug_type *args;
boolean varargs;
/* Constructors are sometimes handled specially. */ /* Constructors are sometimes handled specially. */
is_full_physname_constructor = ((argtypes[0] == '_' is_full_physname_constructor = ((argtypes[0] == '_'
@ -2847,14 +2848,16 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
{ {
args = (debug_type *) xmalloc (sizeof *args); args = (debug_type *) xmalloc (sizeof *args);
*args = NULL; *args = NULL;
return debug_make_method_type (dhandle, return_type, class_type, args); return debug_make_method_type (dhandle, return_type, class_type, args,
false);
} }
args = stab_demangle_argtypes (dhandle, info, *pphysname); args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
if (args == NULL) if (args == NULL)
return DEBUG_TYPE_NULL; return DEBUG_TYPE_NULL;
return debug_make_method_type (dhandle, return_type, class_type, args); return debug_make_method_type (dhandle, return_type, class_type, args,
varargs);
} }
/* The tail end of stabs for C++ classes that contain a virtual function /* The tail end of stabs for C++ classes that contain a virtual function
@ -3492,6 +3495,8 @@ struct stab_demangle_info
struct stab_handle *info; struct stab_handle *info;
/* The array of arguments we are building. */ /* The array of arguments we are building. */
debug_type *args; debug_type *args;
/* Whether the method takes a variable number of arguments. */
boolean varargs;
/* The array of types we have remembered. */ /* The array of types we have remembered. */
struct stab_demangle_typestring *typestrings; struct stab_demangle_typestring *typestrings;
/* The number of typestrings. */ /* The number of typestrings. */
@ -3517,7 +3522,8 @@ static boolean stab_demangle_template
static boolean stab_demangle_class static boolean stab_demangle_class
PARAMS ((struct stab_demangle_info *, const char **, const char **)); PARAMS ((struct stab_demangle_info *, const char **, const char **));
static boolean stab_demangle_args static boolean stab_demangle_args
PARAMS ((struct stab_demangle_info *, const char **, debug_type **)); PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
boolean *));
static boolean stab_demangle_arg static boolean stab_demangle_arg
PARAMS ((struct stab_demangle_info *, const char **, debug_type **, PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
unsigned int *, unsigned int *)); unsigned int *, unsigned int *));
@ -3596,16 +3602,18 @@ stab_demangle_get_count (pp, pi)
terminated array of argument types. */ terminated array of argument types. */
static debug_type * static debug_type *
stab_demangle_argtypes (dhandle, info, physname) stab_demangle_argtypes (dhandle, info, physname, pvarargs)
PTR dhandle; PTR dhandle;
struct stab_handle *info; struct stab_handle *info;
const char *physname; const char *physname;
boolean *pvarargs;
{ {
struct stab_demangle_info minfo; struct stab_demangle_info minfo;
minfo.dhandle = dhandle; minfo.dhandle = dhandle;
minfo.info = info; minfo.info = info;
minfo.args = NULL; minfo.args = NULL;
minfo.varargs = false;
minfo.typestring_alloc = 10; minfo.typestring_alloc = 10;
minfo.typestrings = ((struct stab_demangle_typestring *) minfo.typestrings = ((struct stab_demangle_typestring *)
xmalloc (minfo.typestring_alloc xmalloc (minfo.typestring_alloc
@ -3630,6 +3638,7 @@ stab_demangle_argtypes (dhandle, info, physname)
if (minfo.args == NULL) if (minfo.args == NULL)
fprintf (stderr, "no argument types in mangled string\n"); fprintf (stderr, "no argument types in mangled string\n");
*pvarargs = minfo.varargs;
return minfo.args; return minfo.args;
error_return: error_return:
@ -3820,7 +3829,7 @@ stab_demangle_signature (minfo, pp)
hold = NULL; hold = NULL;
func_done = true; func_done = true;
++*pp; ++*pp;
if (! stab_demangle_args (minfo, pp, &minfo->args)) if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false; return false;
break; break;
@ -3848,7 +3857,7 @@ stab_demangle_signature (minfo, pp)
/* Assume we have stumbled onto the first outermost function /* Assume we have stumbled onto the first outermost function
argument token, and start processing args. */ argument token, and start processing args. */
func_done = true; func_done = true;
if (! stab_demangle_args (minfo, pp, &minfo->args)) if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false; return false;
break; break;
} }
@ -3856,7 +3865,7 @@ stab_demangle_signature (minfo, pp)
if (expect_func) if (expect_func)
{ {
func_done = true; func_done = true;
if (! stab_demangle_args (minfo, pp, &minfo->args)) if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false; return false;
} }
} }
@ -3867,7 +3876,7 @@ stab_demangle_signature (minfo, pp)
bar__3fooi is 'foo::bar(int)'. We get here when we find the bar__3fooi is 'foo::bar(int)'. We get here when we find the
first case, and need to ensure that the '(void)' gets added first case, and need to ensure that the '(void)' gets added
to the current declp. */ to the current declp. */
if (! stab_demangle_args (minfo, pp, &minfo->args)) if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false; return false;
} }
@ -4250,10 +4259,11 @@ stab_demangle_class (minfo, pp, pstart)
is set to a NULL terminated array holding the arguments. */ is set to a NULL terminated array holding the arguments. */
static boolean static boolean
stab_demangle_args (minfo, pp, pargs) stab_demangle_args (minfo, pp, pargs, pvarargs)
struct stab_demangle_info *minfo; struct stab_demangle_info *minfo;
const char **pp; const char **pp;
debug_type **pargs; debug_type **pargs;
boolean *pvarargs;
{ {
const char *orig; const char *orig;
unsigned int alloc, count; unsigned int alloc, count;
@ -4262,7 +4272,10 @@ stab_demangle_args (minfo, pp, pargs)
alloc = 10; alloc = 10;
if (pargs != NULL) if (pargs != NULL)
*pargs = (debug_type *) xmalloc (alloc * sizeof **pargs); {
*pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
*pvarargs = false;
}
count = 0; count = 0;
while (**pp != '_' && **pp != '\0' && **pp != 'e') while (**pp != '_' && **pp != '\0' && **pp != 'e')
@ -4313,32 +4326,16 @@ stab_demangle_args (minfo, pp, pargs)
} }
} }
if (pargs != NULL)
(*pargs)[count] = DEBUG_TYPE_NULL;
if (**pp == 'e') if (**pp == 'e')
{ {
if (pargs != NULL) if (pargs != NULL)
{ *pvarargs = true;
debug_type type;
type = debug_make_ellipsis_type (minfo->dhandle);
if (type == DEBUG_TYPE_NULL)
return false;
if (count + 1 >= alloc)
{
alloc += 10;
*pargs = ((debug_type *)
xrealloc (*pargs, alloc * sizeof **pargs));
}
(*pargs)[count] = type;
++count;
}
++*pp; ++*pp;
} }
if (pargs != NULL)
(*pargs)[count] = DEBUG_TYPE_NULL;
return true; return true;
} }
@ -4478,23 +4475,35 @@ stab_demangle_type (minfo, pp, ptype)
case 'F': case 'F':
/* A function. */ /* A function. */
++*pp; {
/* FIXME: We should pick up the argument types. */ debug_type *args;
if (! stab_demangle_args (minfo, pp, (debug_type **) NULL)) boolean varargs;
return false;
if (**pp != '_') ++*pp;
{ if (! stab_demangle_args (minfo, pp,
/* cplus_demangle will accept a function without a return (ptype == NULL
type, but I don't know when that will happen, or what to ? (debug_type **) NULL
do if it does. */ : &args),
stab_bad_demangle (orig); (ptype == NULL
? (boolean *) NULL
: &varargs)))
return false; return false;
} if (**pp != '_')
++*pp; {
if (! stab_demangle_type (minfo, pp, ptype)) /* cplus_demangle will accept a function without a return
return false; type, but I don't know when that will happen, or what
if (ptype != NULL) to do if it does. */
*ptype = debug_make_function_type (minfo->dhandle, *ptype); stab_bad_demangle (orig);
return false;
}
++*pp;
if (! stab_demangle_type (minfo, pp, ptype))
return false;
if (ptype != NULL)
*ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
varargs);
}
break; break;
case 'M': case 'M':
@ -4502,6 +4511,7 @@ stab_demangle_type (minfo, pp, ptype)
{ {
boolean memberp, constp, volatilep; boolean memberp, constp, volatilep;
debug_type *args; debug_type *args;
boolean varargs;
unsigned int n; unsigned int n;
const char *name; const char *name;
@ -4509,6 +4519,7 @@ stab_demangle_type (minfo, pp, ptype)
constp = false; constp = false;
volatilep = false; volatilep = false;
args = NULL; args = NULL;
varargs = false;
++*pp; ++*pp;
if (! isdigit ((unsigned char) **pp)) if (! isdigit ((unsigned char) **pp))
@ -4546,7 +4557,10 @@ stab_demangle_type (minfo, pp, ptype)
if (! stab_demangle_args (minfo, pp, if (! stab_demangle_args (minfo, pp,
(ptype == NULL (ptype == NULL
? (debug_type **) NULL ? (debug_type **) NULL
: &args))) : &args),
(ptype == NULL
? (boolean *) NULL
: &varargs)))
return false; return false;
} }
@ -4578,7 +4592,7 @@ stab_demangle_type (minfo, pp, ptype)
/* FIXME: We have no way to record constp or /* FIXME: We have no way to record constp or
volatilep. */ volatilep. */
*ptype = debug_make_method_type (minfo->dhandle, *ptype, *ptype = debug_make_method_type (minfo->dhandle, *ptype,
class_type, args); class_type, args, varargs);
} }
} }
} }