* 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:
parent
d3023c8f19
commit
267e52989e
5 changed files with 316 additions and 215 deletions
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue