mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-02 19:46:09 +08:00
* 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:
@ -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.
|
||||
|
110
binutils/debug.c
110
binutils/debug.c
@ -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))
|
||||
|
@ -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. */
|
||||
|
147
binutils/ieee.c
147
binutils/ieee.c
@ -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. */
|
||||
|
162
binutils/stabs.c
162
binutils/stabs.c
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user