diff options
-rw-r--r-- | binutils/ChangeLog | 37 | ||||
-rw-r--r-- | binutils/debug.c | 106 | ||||
-rw-r--r-- | binutils/debug.h | 75 | ||||
-rw-r--r-- | binutils/ieee.c | 147 | ||||
-rw-r--r-- | binutils/stabs.c | 162 |
5 files changed, 314 insertions, 213 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f175405..c21f8f9 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -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. diff --git a/binutils/debug.c b/binutils/debug.c index edb5835..0a6832e 100644 --- a/binutils/debug.c +++ b/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,9 +2221,10 @@ 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; @@ -2242,11 +2234,38 @@ debug_get_parameter_types (handle, type) 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. */ @@ -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)) diff --git a/binutils/debug.h b/binutils/debug.h index d40679b..38ef789 100644 --- a/binutils/debug.h +++ b/binutils/debug.h @@ -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, + 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. */ diff --git a/binutils/ieee.c b/binutils/ieee.c index 0006460..8f0407b 100644 --- a/binutils/ieee.c +++ b/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. */ diff --git a/binutils/stabs.c b/binutils/stabs.c index 76b221b..be9fce0 100644 --- a/binutils/stabs.c +++ b/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); } } } |