* 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>
* 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
functions not listed below to demangle argument types; they are
all called via stab_demangle_argtypes.

View File

@ -184,6 +184,10 @@ struct debug_function_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. */
@ -244,6 +248,8 @@ struct debug_method_type
debug_type domain_type;
/* A NULL terminated array of argument types. */
debug_type *arg_types;
/* Whether the method takes a variable number of arguments. */
boolean varargs;
};
/* Information kept for a named type. */
@ -503,15 +509,6 @@ struct debug_name
} 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. */
static void debug_error PARAMS ((const char *));
@ -1241,18 +1238,6 @@ debug_make_indirect_type (handle, slot, tag)
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. */
debug_type
@ -1458,9 +1443,11 @@ debug_make_pointer_type (handle, type)
to record the parameter types. */
debug_type
debug_make_function_type (handle, type)
debug_make_function_type (handle, type, arg_types, varargs)
PTR handle;
debug_type type;
debug_type *arg_types;
boolean varargs;
{
struct debug_handle *info = (struct debug_handle *) handle;
struct debug_type *t;
@ -1477,6 +1464,8 @@ debug_make_function_type (handle, type)
memset (f, 0, sizeof *f);
f->return_type = type;
f->arg_types = arg_types;
f->varargs = varargs;
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. */
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;
debug_type return_type;
debug_type domain_type;
debug_type *arg_types;
boolean varargs;
{
struct debug_handle *info = (struct debug_handle *) handle;
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->domain_type = domain_type;
m->arg_types = arg_types;
m->varargs = varargs;
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). */
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;
debug_type type;
{
@ -2241,8 +2254,14 @@ debug_get_parameter_types (handle, type)
{
default:
return NULL;
case DEBUG_KIND_METHOD:
return type->u.kmethod->arg_types;
case DEBUG_KIND_POINTER:
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*/
}
@ -2422,6 +2441,7 @@ debug_write_type (info, fns, fhandle, type, name)
struct debug_name *name;
{
unsigned int i;
int is;
const char *tag;
/* 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 (*fns->pointer_type) (fhandle);
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,
type->u.kfunction->return_type,
(struct debug_name *) NULL))
return false;
return (*fns->function_type) (fhandle);
return (*fns->function_type) (fhandle, is,
type->u.kfunction->varargs);
case DEBUG_KIND_REFERENCE:
if (! debug_write_type (info, fns, fhandle, type->u.kreference,
(struct debug_name *) NULL))
@ -2578,24 +2609,14 @@ debug_write_type (info, fns, fhandle, type, name)
(struct debug_name *) NULL))
return false;
if (type->u.kmethod->arg_types == NULL)
i = -1;
is = -1;
else
{
for (i = 0; type->u.kmethod->arg_types[i] != NULL; i++)
{
if (ELLIPSIS_P (type->u.kmethod->arg_types[i]))
{
if (! (*fns->ellipsis_type) (fhandle))
return false;
}
else
{
if (! debug_write_type (info, fns, fhandle,
type->u.kmethod->arg_types[i],
(struct debug_name *) NULL))
return false;
}
}
for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
if (! debug_write_type (info, fns, fhandle,
type->u.kmethod->arg_types[is],
(struct debug_name *) NULL))
return false;
}
if (type->u.kmethod->domain_type != NULL)
{
@ -2606,7 +2627,8 @@ debug_write_type (info, fns, fhandle, type, name)
}
return (*fns->method_type) (fhandle,
type->u.kmethod->domain_type != NULL,
i);
is,
type->u.kmethod->varargs);
case DEBUG_KIND_CONST:
if (! debug_write_type (info, fns, fhandle, type->u.kconst,
(struct debug_name *) NULL))

View File

@ -174,11 +174,6 @@ struct debug_write_fns
/* 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
there is a reference to a type which is never defined. */
boolean (*empty_type) PARAMS ((PTR));
@ -210,9 +205,15 @@ struct debug_write_fns
type onto the type stack. */
boolean (*pointer_type) PARAMS ((PTR));
/* Pop the top type on the type stack, and push a function returning
that type onto the type stack. */
boolean (*function_type) PARAMS ((PTR));
/* Push a function type onto the type stack. The second argument
indicates the number of argument types that have been pushed onto
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
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
number of argument types; these are pushed onto the type stack in
reverse order (the first type popped is the last argument to the
method). An argument type of -1 means that no argument in
formation is available. The next type on the type stack below
the domain and the argument types is the return type of the
method. All these types must be popped, and then the method type
must be pushed. */
boolean (*method_type) PARAMS ((PTR, boolean, int));
method). A value of -1 for the third argument means that no
argument information is available. The fourth argument is true
if the function takes a variable number of arguments. The next
type on the type stack below the domain and the argument types is
the return type of the method. All these types must be popped,
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
version of that type onto the type stack. */
@ -519,13 +521,6 @@ extern boolean debug_record_variable
extern debug_type debug_make_indirect_type
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. */
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
PARAMS ((PTR, debug_type));
/* Make a function returning a given type. FIXME: We should be able
to record the parameter types. */
/* Make a function type. The second argument is the return type. The
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. */
@ -618,14 +617,17 @@ extern debug_type debug_make_offset_type
PARAMS ((PTR, debug_type, debug_type));
/* Make a type for a method function. The second argument is the
return type, the third argument is the domain, and the fourth
argument is a NULL terminated array of argument types. 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. */
return type. The third argument is the domain. The fourth
argument is a NULL terminated array of argument types. The fifth
argument is true if the function takes a variable number of
arguments, in which case the array of argument types indicates the
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
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. */
@ -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
method type (actually, parameter types are not currently stored for
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
class. */

View File

@ -1664,7 +1664,8 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
}
while (present);
type = debug_make_function_type (dhandle, rtype);
type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
false);
return_type = rtype;
}
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;
debug_type rtype;
debug_type *arg_types;
boolean varargs;
boolean present;
/* FIXME: We ignore almost all this information. */
@ -1790,23 +1793,49 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
&rtype)
|| ! ieee_read_number (abfd, bytes, pp, pend, &nargs))
return false;
if (nargs != (bfd_vma) -1)
if (nargs == (bfd_vma) -1)
{
for (; nargs > 0; nargs--)
{
debug_type atype;
arg_types = NULL;
varargs = false;
}
else
{
unsigned int i;
if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp,
pend, &atype))
return false;
arg_types = ((debug_type *)
xmalloc ((nargs + 1) * sizeof *arg_types));
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)
|| ! ieee_read_optional_number (abfd, bytes, pp, pend, &father,
&present))
return false;
type = debug_make_function_type (dhandle, rtype);
type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
return_type = rtype;
}
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_source PARAMS ((PTR, const char *));
static boolean ieee_ellipsis_type PARAMS ((PTR));
static boolean ieee_empty_type PARAMS ((PTR));
static boolean ieee_void_type PARAMS ((PTR));
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
PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
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_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
static boolean ieee_array_type
PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
static boolean ieee_set_type PARAMS ((PTR, boolean));
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_volatile_type PARAMS ((PTR));
static boolean ieee_start_struct_type
@ -2420,7 +2448,6 @@ static const struct debug_write_fns ieee_fns =
{
ieee_start_compilation_unit,
ieee_start_source,
ieee_ellipsis_type,
ieee_empty_type,
ieee_void_type,
ieee_int_type,
@ -3161,15 +3188,6 @@ ieee_start_source (p, filename)
return true;
}
/* Make an ellipsis type. */
static boolean
ieee_ellipsis_type (p)
PTR p;
{
abort ();
}
/* Make an empty type. */
static boolean
@ -3382,27 +3400,53 @@ ieee_pointer_type (p)
/* Make a function type. */
static boolean
ieee_function_type (p)
ieee_function_type (p, argcount, varargs)
PTR p;
int argcount;
boolean varargs;
{
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,
but we didn't store them. */
retindx = ieee_pop_type (info);
/* An attribute of 0x41 means that the frame and push mask are
unknown. */
return (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, indx)
&& ieee_write_number (info, (bfd_vma) -1)
&& ieee_write_number (info, 0));
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 + (varargs ? 1 : 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. */
@ -3520,15 +3564,13 @@ ieee_offset_type (p)
/* Make a method type. */
static boolean
ieee_method_type (p, domain, argcount)
ieee_method_type (p, domain, argcount, varargs)
PTR p;
boolean domain;
int argcount;
boolean varargs;
{
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
method, but the definition is incomplete. We just output an 'x'
@ -3537,32 +3579,7 @@ ieee_method_type (p, domain, argcount)
if (domain)
(void) 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);
}
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);
return ieee_function_type (p, argcount, varargs);
}
/* 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,
enum debug_type_kind));
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. */
@ -827,9 +827,13 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
(debug_type **) NULL);
if (dtype != DEBUG_TYPE_NULL)
dtype = debug_make_pointer_type (dhandle,
debug_make_function_type (dhandle,
dtype));
{
debug_type ftype;
ftype = debug_make_function_type (dhandle, dtype,
(debug_type *) NULL, false);
dtype = debug_make_pointer_type (dhandle, ftype);
}
}
if (dtype == DEBUG_TYPE_NULL)
return false;
@ -1278,7 +1282,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
dtype = (debug_make_function_type
(dhandle,
parse_stab_type (dhandle, info, (const char *) NULL, pp,
(debug_type **) NULL)));
(debug_type **) NULL),
(debug_type *) NULL, false));
break;
case 'k':
@ -1348,7 +1353,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
}
++*pp;
dtype = debug_make_method_type (dhandle, return_type,
DEBUG_TYPE_NULL, NULL);
DEBUG_TYPE_NULL,
(debug_type *) NULL, false);
}
else
{
@ -1357,6 +1363,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
debug_type *args;
unsigned int n;
unsigned int alloc;
boolean varargs;
domain = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
@ -1402,30 +1409,22 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
}
++*pp;
/* If the last type is void, then this function does not
take a variable number of arguments. If the last is not
void, then it does. */
if (n > 0
&& debug_get_type_kind (dhandle, args[n - 1]) == DEBUG_KIND_VOID)
--n;
/* If the last type is not void, then this function takes a
variable number of arguments. Otherwise, we must strip
the void type. */
if (n == 0
|| debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
varargs = true;
else
{
if (n + 1 >= alloc)
{
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;
--n;
varargs = false;
}
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;
@ -2499,6 +2498,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
bfd_vma voffset;
debug_type context;
const char *physname;
boolean varargs;
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. */
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;
else
{
@ -2759,6 +2759,7 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
boolean is_constructor;
boolean is_destructor;
debug_type *args;
boolean varargs;
/* Constructors are sometimes handled specially. */
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 = 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)
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
@ -3492,6 +3495,8 @@ struct stab_demangle_info
struct stab_handle *info;
/* The array of arguments we are building. */
debug_type *args;
/* Whether the method takes a variable number of arguments. */
boolean varargs;
/* The array of types we have remembered. */
struct stab_demangle_typestring *typestrings;
/* The number of typestrings. */
@ -3517,7 +3522,8 @@ static boolean stab_demangle_template
static boolean stab_demangle_class
PARAMS ((struct stab_demangle_info *, const char **, const char **));
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
PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
unsigned int *, unsigned int *));
@ -3596,16 +3602,18 @@ stab_demangle_get_count (pp, pi)
terminated array of argument types. */
static debug_type *
stab_demangle_argtypes (dhandle, info, physname)
stab_demangle_argtypes (dhandle, info, physname, pvarargs)
PTR dhandle;
struct stab_handle *info;
const char *physname;
boolean *pvarargs;
{
struct stab_demangle_info minfo;
minfo.dhandle = dhandle;
minfo.info = info;
minfo.args = NULL;
minfo.varargs = false;
minfo.typestring_alloc = 10;
minfo.typestrings = ((struct stab_demangle_typestring *)
xmalloc (minfo.typestring_alloc
@ -3630,6 +3638,7 @@ stab_demangle_argtypes (dhandle, info, physname)
if (minfo.args == NULL)
fprintf (stderr, "no argument types in mangled string\n");
*pvarargs = minfo.varargs;
return minfo.args;
error_return:
@ -3820,7 +3829,7 @@ stab_demangle_signature (minfo, pp)
hold = NULL;
func_done = true;
++*pp;
if (! stab_demangle_args (minfo, pp, &minfo->args))
if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false;
break;
@ -3848,7 +3857,7 @@ stab_demangle_signature (minfo, pp)
/* Assume we have stumbled onto the first outermost function
argument token, and start processing args. */
func_done = true;
if (! stab_demangle_args (minfo, pp, &minfo->args))
if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false;
break;
}
@ -3856,7 +3865,7 @@ stab_demangle_signature (minfo, pp)
if (expect_func)
{
func_done = true;
if (! stab_demangle_args (minfo, pp, &minfo->args))
if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false;
}
}
@ -3867,7 +3876,7 @@ stab_demangle_signature (minfo, pp)
bar__3fooi is 'foo::bar(int)'. We get here when we find the
first case, and need to ensure that the '(void)' gets added
to the current declp. */
if (! stab_demangle_args (minfo, pp, &minfo->args))
if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
return false;
}
@ -4250,10 +4259,11 @@ stab_demangle_class (minfo, pp, pstart)
is set to a NULL terminated array holding the arguments. */
static boolean
stab_demangle_args (minfo, pp, pargs)
stab_demangle_args (minfo, pp, pargs, pvarargs)
struct stab_demangle_info *minfo;
const char **pp;
debug_type **pargs;
boolean *pvarargs;
{
const char *orig;
unsigned int alloc, count;
@ -4262,7 +4272,10 @@ stab_demangle_args (minfo, pp, pargs)
alloc = 10;
if (pargs != NULL)
*pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
{
*pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
*pvarargs = false;
}
count = 0;
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 (pargs != NULL)
{
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;
}
*pvarargs = true;
++*pp;
}
if (pargs != NULL)
(*pargs)[count] = DEBUG_TYPE_NULL;
return true;
}
@ -4478,23 +4475,35 @@ stab_demangle_type (minfo, pp, ptype)
case 'F':
/* A function. */
++*pp;
/* FIXME: We should pick up the argument types. */
if (! stab_demangle_args (minfo, pp, (debug_type **) NULL))
return false;
if (**pp != '_')
{
/* cplus_demangle will accept a function without a return
type, but I don't know when that will happen, or what to
do if it does. */
stab_bad_demangle (orig);
{
debug_type *args;
boolean varargs;
++*pp;
if (! stab_demangle_args (minfo, pp,
(ptype == NULL
? (debug_type **) NULL
: &args),
(ptype == NULL
? (boolean *) NULL
: &varargs)))
return false;
}
++*pp;
if (! stab_demangle_type (minfo, pp, ptype))
return false;
if (ptype != NULL)
*ptype = debug_make_function_type (minfo->dhandle, *ptype);
if (**pp != '_')
{
/* cplus_demangle will accept a function without a return
type, but I don't know when that will happen, or what
to do if it does. */
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;
case 'M':
@ -4502,6 +4511,7 @@ stab_demangle_type (minfo, pp, ptype)
{
boolean memberp, constp, volatilep;
debug_type *args;
boolean varargs;
unsigned int n;
const char *name;
@ -4509,6 +4519,7 @@ stab_demangle_type (minfo, pp, ptype)
constp = false;
volatilep = false;
args = NULL;
varargs = false;
++*pp;
if (! isdigit ((unsigned char) **pp))
@ -4546,7 +4557,10 @@ stab_demangle_type (minfo, pp, ptype)
if (! stab_demangle_args (minfo, pp,
(ptype == NULL
? (debug_type **) NULL
: &args)))
: &args),
(ptype == NULL
? (boolean *) NULL
: &varargs)))
return false;
}
@ -4578,7 +4592,7 @@ stab_demangle_type (minfo, pp, ptype)
/* FIXME: We have no way to record constp or
volatilep. */
*ptype = debug_make_method_type (minfo->dhandle, *ptype,
class_type, args);
class_type, args, varargs);
}
}
}