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.
{
/* 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. */
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. */
} 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 *));
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
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;
memset (f, 0, sizeof *f);
f->return_type = type;
+ f->arg_types = arg_types;
+ f->varargs = varargs;
t->u.kfunction = f;
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;
m->return_type = return_type;
m->domain_type = domain_type;
m->arg_types = arg_types;
+ m->varargs = varargs;
t->u.kmethod = m;
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;
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;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type);
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ 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*/
+}
+
/* Get the NULL terminated array of fields for a struct, union, or
class. */
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
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))
(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)
{
}
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))
/* 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));
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. */
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. */
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));
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. */
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. */
/* 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,
+ boolean *));
+
+/* Get the target type of a pointer or reference or const or volatile
+ type. */
-extern const debug_type *debug_get_parameter_types PARAMS ((PTR, debug_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. */
}
while (present);
- type = debug_make_function_type (dhandle, rtype);
+ type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
+ false);
return_type = rtype;
}
break;
{
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. */
&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;
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));
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
{
ieee_start_compilation_unit,
ieee_start_source,
- ieee_ellipsis_type,
ieee_empty_type,
ieee_void_type,
ieee_int_type,
return true;
}
-/* Make an ellipsis type. */
-
-static boolean
-ieee_ellipsis_type (p)
- PTR p;
-{
- abort ();
-}
-
/* Make an empty type. */
static boolean
/* 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. */
/* 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'
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. */
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. */
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;
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':
}
++*pp;
dtype = debug_make_method_type (dhandle, return_type,
- DEBUG_TYPE_NULL, NULL);
+ DEBUG_TYPE_NULL,
+ (debug_type *) NULL, false);
}
else
{
debug_type *args;
unsigned int n;
unsigned int alloc;
+ boolean varargs;
domain = parse_stab_type (dhandle, info, (const char *) NULL,
pp, (debug_type **) NULL);
}
++*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;
bfd_vma voffset;
debug_type context;
const char *physname;
+ boolean varargs;
if (look_ahead_type != DEBUG_TYPE_NULL)
{
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
{
boolean is_constructor;
boolean is_destructor;
debug_type *args;
+ boolean varargs;
/* Constructors are sometimes handled specially. */
is_full_physname_constructor = ((argtypes[0] == '_'
{
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
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. */
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 *));
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
if (minfo.args == NULL)
fprintf (stderr, "no argument types in mangled string\n");
+ *pvarargs = minfo.varargs;
return minfo.args;
error_return:
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;
/* 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;
}
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;
}
}
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;
}
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;
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')
}
}
+ 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;
}
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':
{
boolean memberp, constp, volatilep;
debug_type *args;
+ boolean varargs;
unsigned int n;
const char *name;
constp = false;
volatilep = false;
args = NULL;
+ varargs = false;
++*pp;
if (! isdigit ((unsigned char) **pp))
if (! stab_demangle_args (minfo, pp,
(ptype == NULL
? (debug_type **) NULL
- : &args)))
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
return false;
}
/* 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);
}
}
}