This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: RFA: Switch TYPE_CODE_METHOD to store arguments like TYPE_CODE_FUNCTION
- From: Jim Blandy <jimb at redhat dot com>
- To: Daniel Jacobowitz <drow at mvista dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: 13 Jun 2002 20:10:19 -0500
- Subject: Re: RFA: Switch TYPE_CODE_METHOD to store arguments like TYPE_CODE_FUNCTION
- References: <20020604024456.GA8733@branoic.them.org>
This patch is approved.
Although I have looked at each hunk in context, I admit I haven't
followed everything down to the last pointer dereference. However,
this is a nice cleanup that's been a long time coming; even if there
are some bugs, I think GDB is better off with the patch than without.
It causes no regressions with -gstabs+ or -gdwarf-2 -g3.
Daniel Jacobowitz <drow@mvista.com> writes:
> Functions already stored arguments in a list of 'struct field' in their type
> structure, and methods had type_specific.arg_types. I've unified the two,
> as per an earlier conversation with Elena. This let me simplify a lot of
> code (and find a few more bugs in simplifying C++ overload resolution, I
> think; or at least, quirks). This doesn't touch anything that I don't
> consider C++ specific, but there's a great deal of it, so I'd appreciate it
> if someone (Elena?) would review it.
>
> One followup patch will be to recognize the 'artificial' field for both
> function and method arguments. That's one more step down the road of proper
> class printing...
>
> --
> Daniel Jacobowitz Carnegie Mellon University
> MontaVista Software Debian GNU/Linux Developer
>
> 2002-06-03 Daniel Jacobowitz <drow@mvista.com>
>
> * gdbtypes.h (TYPE_FLAG_VARARGS): Update comment.
> (struct main_type): Remove arg_types member. Update comments for
> struct field.
> (TYPE_ARG_TYPES): Remove.
> (TYPE_FN_FIELD_ARGS): Update.
> (smash_to_method_type): Update prototype.
>
> * c-typeprint.c (cp_type_print_method_args): Take method type
> instead of argument list. Use new argument layout. Simplify.
> (c_type_print_args): Use new argument layout. Simplify.
> (c_type_print_base): Update call to cp_type_print_method_args.
> * dwarf2read.c (dwarf2_add_member_fn): Remove unneeded type
> argument; use die->type instead. Update call to
> smash_to_method_type.
> (read_structure_scope): Update call to dwarf2_add_member_fn.
> * gdbtypes.c (allocate_stub_method): Update comment.
> (smash_to_method_type): Take new NARGS and VARARGS arguments.
> Use new argument layout.
> (check_stub_method): Use new argument layout. Don't count
> void as an argument.
> (print_arg_types): Update comments. Use new argument layout.
> (recursive_dump_type): Don't print arg_types member.
> * hpread.c (hpread_read_struct_type): Use new argument layout.
> (fixup_class_method_type): Likewise.
> (hpread_type_lookup): Likewise.
> * stabsread.c (read_type): Update calls to read_args and
> smash_to_method_type.
> (read_args): Use new argument layout. Simplify.
> * valops.c (typecmp): Use new argument layout. Update parameters
> and comments. Simplify.
> (hand_function_call): Use new argument layout.
> (search_struct_method): Update call to typecmp.
> (find_overload_match): Use new argument layout.
>
> diff -upr -x testsuite src-clean/gdb/c-typeprint.c src-meth/gdb/c-typeprint.c
> --- src-clean/gdb/c-typeprint.c Tue May 14 14:30:50 2002
> +++ src-meth/gdb/c-typeprint.c Mon Jun 3 17:01:01 2002
> @@ -41,7 +41,7 @@
> /* Flag indicating target was compiled by HP compiler */
> extern int hp_som_som_object_present;
>
> -static void cp_type_print_method_args (struct type ** args, char *prefix,
> +static void cp_type_print_method_args (struct type *mtype, char *prefix,
> char *varstring, int staticp,
> struct ui_file *stream);
>
> @@ -147,40 +147,40 @@ cp_type_print_derivation_info (struct ui
> fputs_filtered (" ", stream);
> }
> }
> +
> /* Print the C++ method arguments ARGS to the file STREAM. */
>
> static void
> -cp_type_print_method_args (struct type **args, char *prefix, char *varstring,
> +cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring,
> int staticp, struct ui_file *stream)
> {
> + struct field *args = TYPE_FIELDS (mtype);
> + int nargs = TYPE_NFIELDS (mtype);
> + int varargs = TYPE_VARARGS (mtype);
> int i;
>
> fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI);
> fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI);
> fputs_filtered ("(", stream);
> - if (args && args[!staticp] && TYPE_CODE (args[!staticp]) != TYPE_CODE_VOID)
> +
> + /* Skip the class variable. */
> + i = staticp ? 0 : 1;
> + if (nargs > i)
> {
> - i = !staticp; /* skip the class variable */
> - while (1)
> + while (i < nargs)
> {
> - type_print (args[i++], "", stream, 0);
> - if (!args[i])
> - {
> - fprintf_filtered (stream, " ...");
> - break;
> - }
> - else if (TYPE_CODE (args[i]) != TYPE_CODE_VOID)
> - {
> - fprintf_filtered (stream, ", ");
> - }
> - else
> - break;
> + type_print (args[i++].type, "", stream, 0);
> +
> + if (i == nargs && varargs)
> + fprintf_filtered (stream, ", ...");
> + else if (i < nargs)
> + fprintf_filtered (stream, ", ");
> }
> }
> + else if (varargs)
> + fprintf_filtered (stream, "...");
> else if (current_language->la_language == language_cplus)
> - {
> - fprintf_filtered (stream, "void");
> - }
> + fprintf_filtered (stream, "void");
>
> fprintf_filtered (stream, ")");
> }
> @@ -336,39 +336,31 @@ static void
> c_type_print_args (struct type *type, struct ui_file *stream)
> {
> int i;
> - struct type **args;
> + struct field *args;
>
> fprintf_filtered (stream, "(");
> - args = TYPE_ARG_TYPES (type);
> + args = TYPE_FIELDS (type);
> if (args != NULL)
> {
> - if (args[1] == NULL)
> - {
> - fprintf_filtered (stream, "...");
> - }
> - else if ((TYPE_CODE (args[1]) == TYPE_CODE_VOID) &&
> - (current_language->la_language == language_cplus))
> - {
> - fprintf_filtered (stream, "void");
> - }
> - else
> + int i;
> +
> + /* FIXME drow/2002-05-31: Always skips the first argument,
> + should we be checking for static members? */
> +
> + for (i = 1; i < TYPE_NFIELDS (type); i++)
> {
> - for (i = 1;
> - args[i] != NULL && TYPE_CODE (args[i]) != TYPE_CODE_VOID;
> - i++)
> + c_print_type (args[i].type, "", stream, -1, 0);
> + if (i != TYPE_NFIELDS (type))
> {
> - c_print_type (args[i], "", stream, -1, 0);
> - if (args[i + 1] == NULL)
> - {
> - fprintf_filtered (stream, "...");
> - }
> - else if (TYPE_CODE (args[i + 1]) != TYPE_CODE_VOID)
> - {
> - fprintf_filtered (stream, ",");
> - wrap_here (" ");
> - }
> + fprintf_filtered (stream, ",");
> + wrap_here (" ");
> }
> }
> + if (TYPE_VARARGS (type))
> + fprintf_filtered (stream, "...");
> + else if (i == 1
> + && (current_language->la_language == language_cplus))
> + fprintf_filtered (stream, "void");
> }
> else if (current_language->la_language == language_cplus)
> {
> @@ -1010,10 +1002,15 @@ c_type_print_base (struct type *type, st
> Let's try to reconstruct the function signature from
> the symbol information */
> if (!TYPE_FN_FIELD_STUB (f, j))
> - cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
> - method_name,
> - TYPE_FN_FIELD_STATIC_P (f, j),
> - stream);
> + {
> + int staticp = TYPE_FN_FIELD_STATIC_P (f, j);
> + struct type *mtype = TYPE_FN_FIELD_TYPE (f, j);
> + cp_type_print_method_args (mtype,
> + "",
> + method_name,
> + staticp,
> + stream);
> + }
> else
> fprintf_filtered (stream, "<badly mangled name '%s'>",
> mangled_name);
> diff -upr -x testsuite src-clean/gdb/dwarf2read.c src-meth/gdb/dwarf2read.c
> --- src-clean/gdb/dwarf2read.c Sun May 26 10:54:24 2002
> +++ src-meth/gdb/dwarf2read.c Mon Jun 3 17:10:20 2002
> @@ -799,8 +799,7 @@ static void dwarf2_attach_fields_to_type
> struct type *, struct objfile *);
>
> static void dwarf2_add_member_fn (struct field_info *,
> - struct die_info *, struct type *,
> - struct objfile *objfile,
> + struct die_info *, struct objfile *objfile,
> const struct comp_unit_head *);
>
> static void dwarf2_attach_fn_fields_to_type (struct field_info *,
> @@ -2233,7 +2232,7 @@ dwarf2_attach_fields_to_type (struct fie
>
> static void
> dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
> - struct type *type, struct objfile *objfile,
> + struct objfile *objfile,
> const struct comp_unit_head *cu_header)
> {
> struct attribute *attr;
> @@ -2299,23 +2298,13 @@ dwarf2_add_member_fn (struct field_info
> if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
> {
> struct type *return_type = TYPE_TARGET_TYPE (die->type);
> - struct type **arg_types;
> int nparams = TYPE_NFIELDS (die->type);
> - int iparams;
>
> - /* Copy argument types from the subroutine type. */
> - arg_types = (struct type **)
> - TYPE_ALLOC (fnp->type, (nparams + 1) * sizeof (struct type *));
> - for (iparams = 0; iparams < nparams; iparams++)
> - arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams);
> -
> - /* Set last entry in argument type vector. */
> - if (TYPE_VARARGS (die->type))
> - arg_types[nparams] = NULL;
> - else
> - arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID);
> -
> - smash_to_method_type (fnp->type, type, return_type, arg_types);
> + smash_to_method_type (fnp->type, die->type,
> + TYPE_TARGET_TYPE (die->type),
> + TYPE_FIELDS (die->type),
> + TYPE_NFIELDS (die->type),
> + TYPE_VARARGS (die->type));
>
> /* Handle static member functions.
> Dwarf2 has no clean way to discern C++ static and non-static
> @@ -2485,7 +2474,7 @@ read_structure_scope (struct die_info *d
> {
> /* C++ member function. */
> process_die (child_die, objfile, cu_header);
> - dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header);
> + dwarf2_add_member_fn (&fi, child_die, objfile, cu_header);
> }
> else if (child_die->tag == DW_TAG_inheritance)
> {
> diff -upr -x testsuite src-clean/gdb/gdbtypes.c src-meth/gdb/gdbtypes.c
> --- src-clean/gdb/gdbtypes.c Tue May 14 14:30:50 2002
> +++ src-meth/gdb/gdbtypes.c Mon Jun 3 16:51:24 2002
> @@ -127,7 +127,7 @@ static void add_mangled_type (struct ext
> static void cfront_mangle_name (struct type *, int, int);
> #endif
> static void print_bit_vector (B_TYPE *, int);
> -static void print_arg_types (struct type **, int);
> +static void print_arg_types (struct field *, int, int);
> static void dump_fn_fieldlists (struct type *, int);
> static void print_cplus_stuff (struct type *, int);
> static void virtual_base_list_aux (struct type *dclass);
> @@ -576,7 +576,6 @@ allocate_stub_method (struct type *type)
> TYPE_OBJFILE (type));
> TYPE_TARGET_TYPE (mtype) = type;
> /* _DOMAIN_TYPE (mtype) = unknown yet */
> - /* _ARG_TYPES (mtype) = unknown yet */
> return (mtype);
> }
>
> @@ -879,7 +878,8 @@ smash_to_member_type (struct type *type,
>
> void
> smash_to_method_type (struct type *type, struct type *domain,
> - struct type *to_type, struct type **args)
> + struct type *to_type, struct field *args,
> + int nargs, int varargs)
> {
> struct objfile *objfile;
>
> @@ -889,7 +889,10 @@ smash_to_method_type (struct type *type,
> TYPE_OBJFILE (type) = objfile;
> TYPE_TARGET_TYPE (type) = to_type;
> TYPE_DOMAIN_TYPE (type) = domain;
> - TYPE_ARG_TYPES (type) = args;
> + TYPE_FIELDS (type) = args;
> + TYPE_NFIELDS (type) = nargs;
> + if (varargs)
> + TYPE_FLAGS (type) |= TYPE_FLAG_VARARGS;
> TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
> TYPE_CODE (type) = TYPE_CODE_METHOD;
> }
> @@ -1593,7 +1596,7 @@ check_stub_method (struct type *type, in
> DMGL_PARAMS | DMGL_ANSI);
> char *argtypetext, *p;
> int depth = 0, argcount = 1;
> - struct type **argtypes;
> + struct field *argtypes;
> struct type *mtype;
>
> /* Make sure we got back a function string that we can use. */
> @@ -1626,11 +1629,14 @@ check_stub_method (struct type *type, in
> p += 1;
> }
>
> - /* We need two more slots: one for the THIS pointer, and one for the
> - NULL [...] or void [end of arglist]. */
> + /* If we read one argument and it was ``void'', don't count it. */
> + if (strncmp (argtypetext, "(void)", 6) == 0)
> + argcount -= 1;
>
> - argtypes = (struct type **)
> - TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
> + /* We need one extra slot, for the THIS pointer. */
> +
> + argtypes = (struct field *)
> + TYPE_ALLOC (type, (argcount + 1) * sizeof (struct field));
> p = argtypetext;
>
> /* Add THIS pointer for non-static methods. */
> @@ -1639,7 +1645,7 @@ check_stub_method (struct type *type, in
> argcount = 0;
> else
> {
> - argtypes[0] = lookup_pointer_type (type);
> + argtypes[0].type = lookup_pointer_type (type);
> argcount = 1;
> }
>
> @@ -1650,10 +1656,12 @@ check_stub_method (struct type *type, in
> {
> if (depth <= 0 && (*p == ',' || *p == ')'))
> {
> - /* Avoid parsing of ellipsis, they will be handled below. */
> - if (strncmp (argtypetext, "...", p - argtypetext) != 0)
> + /* Avoid parsing of ellipsis, they will be handled below.
> + Also avoid ``void'' as above. */
> + if (strncmp (argtypetext, "...", p - argtypetext) != 0
> + && strncmp (argtypetext, "void", p - argtypetext) != 0)
> {
> - argtypes[argcount] =
> + argtypes[argcount].type =
> safe_parse_type (argtypetext, p - argtypetext);
> argcount += 1;
> }
> @@ -1673,25 +1681,19 @@ check_stub_method (struct type *type, in
> }
> }
>
> - if (p[-2] != '.') /* Not '...' */
> - {
> - argtypes[argcount] = builtin_type_void; /* List terminator */
> - }
> - else
> - {
> - argtypes[argcount] = NULL; /* Ellist terminator */
> - }
> -
> - xfree (demangled_name);
> -
> TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name;
>
> /* Now update the old "stub" type into a real type. */
> mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
> TYPE_DOMAIN_TYPE (mtype) = type;
> - TYPE_ARG_TYPES (mtype) = argtypes;
> + TYPE_FIELDS (mtype) = argtypes;
> + TYPE_NFIELDS (mtype) = argcount;
> TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
> TYPE_FN_FIELD_STUB (f, signature_id) = 0;
> + if (p[-2] == '.')
> + TYPE_FLAGS (mtype) |= TYPE_FLAG_VARARGS;
> +
> + xfree (demangled_name);
> }
>
> const struct cplus_struct_type cplus_struct_default;
> @@ -2682,25 +2684,18 @@ print_bit_vector (B_TYPE *bits, int nbit
> }
> }
>
> -/* The args list is a strange beast. It is either terminated by a NULL
> - pointer for varargs functions, or by a pointer to a TYPE_CODE_VOID
> - type for normal fixed argcount functions. (FIXME someday)
> - Also note the first arg should be the "this" pointer, we may not want to
> - include it since we may get into a infinitely recursive situation. */
> +/* Note the first arg should be the "this" pointer, we may not want to
> + include it since we may get into a infinitely recursive situation. */
>
> static void
> -print_arg_types (struct type **args, int spaces)
> +print_arg_types (struct field *args, int nargs, int spaces)
> {
> if (args != NULL)
> {
> - while (*args != NULL)
> - {
> - recursive_dump_type (*args, spaces + 2);
> - if (TYPE_CODE (*args++) == TYPE_CODE_VOID)
> - {
> - break;
> - }
> - }
> + int i;
> +
> + for (i = 0; i < nargs; i++)
> + recursive_dump_type (args[i].type, spaces + 2);
> }
> }
>
> @@ -2745,7 +2740,9 @@ dump_fn_fieldlists (struct type *type, i
> gdb_print_host_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
> printf_filtered ("\n");
>
> - print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces);
> + print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx),
> + TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, overload_idx)),
> + spaces);
> printfi_filtered (spaces + 8, "fcontext ");
> gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
> gdb_stdout);
> @@ -3087,14 +3084,6 @@ recursive_dump_type (struct type *type,
> printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type));
> switch (TYPE_CODE (type))
> {
> - case TYPE_CODE_METHOD:
> - case TYPE_CODE_FUNC:
> - printfi_filtered (spaces, "arg_types ");
> - gdb_print_host_address (TYPE_ARG_TYPES (type), gdb_stdout);
> - puts_filtered ("\n");
> - print_arg_types (TYPE_ARG_TYPES (type), spaces);
> - break;
> -
> case TYPE_CODE_STRUCT:
> printfi_filtered (spaces, "cplus_stuff ");
> gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
> diff -upr -x testsuite src-clean/gdb/gdbtypes.h src-meth/gdb/gdbtypes.h
> --- src-clean/gdb/gdbtypes.h Wed May 15 23:59:58 2002
> +++ src-meth/gdb/gdbtypes.h Mon Jun 3 22:19:34 2002
> @@ -240,10 +240,8 @@ enum type_code
> #define TYPE_FLAG_DATA_SPACE (1 << 10)
> #define TYPE_DATA_SPACE(t) (TYPE_INSTANCE_FLAGS (t) & TYPE_FLAG_DATA_SPACE)
>
> -/* FIXME: Kludge to mark a varargs function type for C++ member
> - function argument processing. Currently only used in dwarf2read.c,
> - but put it here so we won't accidentally overload the bit with
> - another flag. */
> +/* FIXME drow/2002-06-03: Only used for methods, but applies as well
> + to functions. */
>
> #define TYPE_FLAG_VARARGS (1 << 11)
> #define TYPE_VARARGS(t) (TYPE_FLAGS (t) & TYPE_FLAG_VARARGS)
> @@ -354,7 +352,7 @@ struct main_type
> For range types, there are two "fields",
> the minimum and maximum values (both inclusive).
> For enum types, each possible value is described by one "field".
> - For a function type, a "field" for each parameter type.
> + For a function or method type, a "field" for each parameter.
> For C++ classes, there is one field for each base class (if it is
> a derived class) plus one field for each class data member. Member
> functions are recorded elsewhere.
> @@ -383,7 +381,7 @@ struct main_type
> CORE_ADDR physaddr;
> char *physname;
>
> - /* For a function type, this is 1 if the argument is marked
> + /* For a function or member type, this is 1 if the argument is marked
> artificial. Artificial arguments should not be shown to the
> user. */
> int artificial;
> @@ -400,13 +398,14 @@ struct main_type
> int bitsize;
>
> /* In a struct or union type, type of this field.
> - In a function type, type of this argument.
> + In a function or member type, type of this argument.
> In an array type, the domain-type of the array. */
>
> struct type *type;
>
> /* Name of field, value or argument.
> - NULL for range bounds and array domains. */
> + NULL for range bounds, array domains, and member function
> + arguments. */
>
> char *name;
>
> @@ -438,14 +437,6 @@ struct main_type
>
> union type_specific
> {
> - /* ARG_TYPES is for TYPE_CODE_METHOD.
> - Contains the type of each argument, ending with a void type
> - after the last argument for normal member functions or a NULL
> - pointer after the last argument for functions with variable
> - arguments. */
> -
> - struct type **arg_types;
> -
> /* CPLUS_STUFF is for TYPE_CODE_STRUCT. It is initialized to point to
> cplus_struct_default, a default static instance of a struct
> cplus_struct_type. */
> @@ -785,7 +776,6 @@ extern void allocate_cplus_struct_type (
> #define TYPE_NINSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->ninstantiations
> #define TYPE_DECLARED_TYPE(thistype) TYPE_CPLUS_SPECIFIC(thistype)->declared_type
> #define TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific
> -#define TYPE_ARG_TYPES(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.arg_types
> #define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
> #define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
> #define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type
> @@ -863,7 +853,7 @@ extern void allocate_cplus_struct_type (
> #define TYPE_FN_FIELD(thisfn, n) (thisfn)[n]
> #define TYPE_FN_FIELD_PHYSNAME(thisfn, n) (thisfn)[n].physname
> #define TYPE_FN_FIELD_TYPE(thisfn, n) (thisfn)[n].type
> -#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_ARG_TYPES ((thisfn)[n].type)
> +#define TYPE_FN_FIELD_ARGS(thisfn, n) TYPE_FIELDS ((thisfn)[n].type)
> #define TYPE_FN_FIELD_CONST(thisfn, n) ((thisfn)[n].is_const)
> #define TYPE_FN_FIELD_VOLATILE(thisfn, n) ((thisfn)[n].is_volatile)
> #define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private)
> @@ -1087,8 +1077,9 @@ extern struct type *make_type_with_addre
> extern struct type *lookup_member_type (struct type *, struct type *);
>
> extern void
> -smash_to_method_type (struct type *, struct type *, struct type *,
> - struct type **);
> +smash_to_method_type (struct type *type, struct type *domain,
> + struct type *to_type, struct field *args,
> + int nargs, int varargs);
>
> extern void
> smash_to_member_type (struct type *, struct type *, struct type *);
> diff -upr -x testsuite src-clean/gdb/hpread.c src-meth/gdb/hpread.c
> --- src-clean/gdb/hpread.c Wed May 15 23:59:58 2002
> +++ src-meth/gdb/hpread.c Mon Jun 3 17:03:44 2002
> @@ -3959,26 +3959,9 @@ hpread_read_struct_type (dnttpointer hp_
> /* But mark it as NULL if the method was incompletely processed
> We'll fix this up later when the method is fully processed */
> if (TYPE_INCOMPLETE (memtype))
> - {
> - fn_p->field.fn_fields[ix].type = NULL;
> - }
> + fn_p->field.fn_fields[ix].type = NULL;
> else
> - {
> - fn_p->field.fn_fields[ix].type = memtype;
> -
> - /* The argument list */
> - TYPE_TYPE_SPECIFIC (fn_p->field.fn_fields[ix].type).arg_types
> - = (struct type **) obstack_alloc (&objfile->type_obstack,
> - (sizeof (struct type *)
> - * (TYPE_NFIELDS (memtype)
> - + 1)));
> - for (i = 0; i < TYPE_NFIELDS (memtype); i++)
> - TYPE_TYPE_SPECIFIC (fn_p->field.fn_fields[ix].type)
> - .arg_types[i] = TYPE_FIELDS (memtype)[i].type;
> - /* void termination */
> - TYPE_TYPE_SPECIFIC (fn_p->field.fn_fields[ix].type)
> - .arg_types[TYPE_NFIELDS (memtype)] = builtin_type_void;
> - }
> + fn_p->field.fn_fields[ix].type = memtype;
>
> /* For virtual functions, fill in the voffset field with the
> * virtual table offset. (This is just copied over from the
> @@ -4455,14 +4438,6 @@ fixup_class_method_type (struct type *cl
> {
> /* Set the method type */
> TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
> - /* The argument list */
> - TYPE_TYPE_SPECIFIC (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j)).arg_types
> - = (struct type **) obstack_alloc (&objfile->type_obstack,
> - sizeof (struct type *) * (TYPE_NFIELDS (method) + 1));
> - for (k = 0; k < TYPE_NFIELDS (method); k++)
> - TYPE_TYPE_SPECIFIC (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j)).arg_types[k] = TYPE_FIELDS (method)[k].type;
> - /* void termination */
> - TYPE_TYPE_SPECIFIC (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j)).arg_types[TYPE_NFIELDS (method)] = builtin_type_void;
>
> /* Break out of both loops -- only one method to fix up in a class */
> goto finish;
> @@ -4916,21 +4891,18 @@ hpread_type_lookup (dnttpointer hp_type,
> struct type *retvaltype;
> int nargs;
> int i;
> - struct type **args_type;
> class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
> objfile);
> functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
> objfile);
> retvaltype = TYPE_TARGET_TYPE (functype);
> nargs = TYPE_NFIELDS (functype);
> - args_type = (struct type **) xmalloc ((nargs + 1) * sizeof (struct type *));
> - for (i = 0; i < nargs; i++)
> - {
> - args_type[i] = TYPE_FIELD_TYPE (functype, i);
> - }
> - args_type[nargs] = NULL;
> ptrmemtype = alloc_type (objfile);
> - smash_to_method_type (ptrmemtype, class_type, retvaltype, args_type);
> +
> + smash_to_method_type (ptrmemtype, class_type, retvaltype,
> + TYPE_FIELDS (functype),
> + TYPE_NFIELDS (functype),
> + 0);
> return make_pointer_type (ptrmemtype, NULL);
> }
> break;
> diff -upr -x testsuite src-clean/gdb/stabsread.c src-meth/gdb/stabsread.c
> --- src-clean/gdb/stabsread.c Tue May 14 14:30:51 2002
> +++ src-meth/gdb/stabsread.c Mon Jun 3 15:25:41 2002
> @@ -142,7 +142,7 @@ static struct type *read_struct_type (ch
> static struct type *read_array_type (char **, struct type *,
> struct objfile *);
>
> -static struct type **read_args (char **, int, struct objfile *);
> +static struct field *read_args (char **, int, struct objfile *, int *, int *);
>
> static int
> read_cpp_abbrev (struct field_info *, char **, struct type *,
> @@ -2780,7 +2780,8 @@ again:
> {
> struct type *domain = read_type (pp, objfile);
> struct type *return_type;
> - struct type **args;
> + struct field *args;
> + int nargs, varargs;
>
> if (**pp != ',')
> /* Invalid member type data format. */
> @@ -2789,9 +2790,10 @@ again:
> ++(*pp);
>
> return_type = read_type (pp, objfile);
> - args = read_args (pp, ';', objfile);
> + args = read_args (pp, ';', objfile, &nargs, &varargs);
> type = dbx_alloc_type (typenums, objfile);
> - smash_to_method_type (type, domain, return_type, args);
> + smash_to_method_type (type, domain, return_type, args,
> + nargs, varargs);
> }
> break;
>
> @@ -4929,38 +4931,39 @@ handle_true_range:
> and terminated with END. Return the list of types read in, or (struct type
> **)-1 if there is an error. */
>
> -static struct type **
> -read_args (char **pp, int end, struct objfile *objfile)
> +static struct field *
> +read_args (char **pp, int end, struct objfile *objfile, int *nargsp,
> + int *varargsp)
> {
> /* FIXME! Remove this arbitrary limit! */
> - struct type *types[1024], **rval; /* allow for fns of 1023 parameters */
> - int n = 0;
> + struct type *types[1024]; /* allow for fns of 1023 parameters */
> + int n = 0, i;
> + struct field *rval;
>
> while (**pp != end)
> {
> if (**pp != ',')
> /* Invalid argument list: no ','. */
> - return (struct type **) -1;
> + return (struct field *) -1;
> (*pp)++;
> STABS_CONTINUE (pp, objfile);
> types[n++] = read_type (pp, objfile);
> }
> (*pp)++; /* get past `end' (the ':' character) */
>
> - if (n == 1)
> - {
> - rval = (struct type **) xmalloc (2 * sizeof (struct type *));
> - }
> - else if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
> - {
> - rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *));
> - memset (rval + n, 0, sizeof (struct type *));
> - }
> + if (TYPE_CODE (types[n - 1]) != TYPE_CODE_VOID)
> + *varargsp = 1;
> else
> {
> - rval = (struct type **) xmalloc (n * sizeof (struct type *));
> + n--;
> + *varargsp = 0;
> }
> - memcpy (rval, types, n * sizeof (struct type *));
> +
> + rval = (struct field *) xmalloc (n * sizeof (struct field));
> + memset (rval, 0, n * sizeof (struct field));
> + for (i = 0; i < n; i++)
> + rval[i].type = types[i];
> + *nargsp = n;
> return rval;
> }
>
> diff -upr -x testsuite src-clean/gdb/valops.c src-meth/gdb/valops.c
> --- src-clean/gdb/valops.c Mon May 13 10:00:36 2002
> +++ src-meth/gdb/valops.c Mon Jun 3 14:59:28 2002
> @@ -45,7 +45,8 @@ extern int hp_som_som_object_present;
> extern int overload_debug;
> /* Local functions. */
>
> -static int typecmp (int staticp, struct type *t1[], struct value *t2[]);
> +static int typecmp (int staticp, int varargs, int nargs,
> + struct field t1[], struct value *t2[]);
>
> static CORE_ADDR find_function_addr (struct value *, struct type **);
> static struct value *value_arg_coerce (struct value *, struct type *, int);
> @@ -1438,42 +1439,25 @@ hand_function_call (struct value *functi
> sp = old_sp; /* It really is used, for some ifdef's... */
> #endif
>
> - if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
> - {
> - i = 0;
> - while (TYPE_CODE (TYPE_ARG_TYPES (ftype)[i]) != TYPE_CODE_VOID)
> - i++;
> - n_method_args = i;
> - if (nargs < i)
> - error ("too few arguments in method call");
> - }
> - else if (nargs < TYPE_NFIELDS (ftype))
> + if (nargs < TYPE_NFIELDS (ftype))
> error ("too few arguments in function call");
>
> for (i = nargs - 1; i >= 0; i--)
> {
> - /* Assume that methods are always prototyped, unless they are off the
> - end (which we should only be allowing if there is a ``...'').
> - FIXME. */
> - if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
> - {
> - if (i < n_method_args)
> - args[i] = value_arg_coerce (args[i], TYPE_ARG_TYPES (ftype)[i], 1);
> - else
> - args[i] = value_arg_coerce (args[i], NULL, 0);
> - }
> + int prototyped;
>
> - /* If we're off the end of the known arguments, do the standard
> - promotions. FIXME: if we had a prototype, this should only
> - be allowed if ... were present. */
> - if (i >= TYPE_NFIELDS (ftype))
> - args[i] = value_arg_coerce (args[i], NULL, 0);
> + /* FIXME drow/2002-05-31: Should just always mark methods as
> + prototyped. Can we respect TYPE_VARARGS? Probably not. */
> + if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
> + prototyped = 1;
> + else
> + prototyped = TYPE_PROTOTYPED (ftype);
>
> + if (i < TYPE_NFIELDS (ftype))
> + args[i] = value_arg_coerce (args[i], TYPE_FIELD_TYPE (ftype, i),
> + prototyped);
> else
> - {
> - param_type = TYPE_FIELD_TYPE (ftype, i);
> - args[i] = value_arg_coerce (args[i], param_type, TYPE_PROTOTYPED (ftype));
> - }
> + args[i] = value_arg_coerce (args[i], NULL, 0);
>
> /*elz: this code is to handle the case in which the function to be called
> has a pointer to function as parameter and the corresponding actual argument
> @@ -1485,7 +1469,7 @@ hand_function_call (struct value *functi
> In cc this is not a problem. */
>
> if (using_gcc == 0)
> - if (param_type)
> + if (param_type && TYPE_CODE (ftype) != TYPE_CODE_METHOD)
> /* if this parameter is a pointer to function */
> if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
> if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
> @@ -1938,13 +1922,14 @@ value_bitstring (char *ptr, int len)
> }
>
> /* See if we can pass arguments in T2 to a function which takes arguments
> - of types T1. Both t1 and t2 are NULL-terminated vectors. If some
> - arguments need coercion of some sort, then the coerced values are written
> - into T2. Return value is 0 if the arguments could be matched, or the
> - position at which they differ if not.
> + of types T1. T1 is a list of NARGS arguments, and T2 is a NULL-terminated
> + vector. If some arguments need coercion of some sort, then the coerced
> + values are written into T2. Return value is 0 if the arguments could be
> + matched, or the position at which they differ if not.
>
> STATICP is nonzero if the T1 argument list came from a
> - static member function.
> + static member function. T2 will still include the ``this'' pointer,
> + but it will be skipped.
>
> For non-static member functions, we ignore the first argument,
> which is the type of the instance variable. This is because we want
> @@ -1953,30 +1938,30 @@ value_bitstring (char *ptr, int len)
> requested operation is type secure, shouldn't we? FIXME. */
>
> static int
> -typecmp (int staticp, struct type *t1[], struct value *t2[])
> +typecmp (int staticp, int varargs, int nargs,
> + struct field t1[], struct value *t2[])
> {
> int i;
>
> if (t2 == 0)
> - return 1;
> - if (staticp && t1 == 0)
> - return t2[1] != 0;
> - if (t1 == 0)
> - return 1;
> - if (t1[!staticp] == 0)
> - return 0;
> - if (TYPE_CODE (t1[0]) == TYPE_CODE_VOID)
> - return 0;
> + internal_error (__FILE__, __LINE__, "typecmp: no argument list");
> +
> /* Skip ``this'' argument if applicable. T2 will always include THIS. */
> if (staticp)
> - t2++;
> - for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
> + t2 ++;
> +
> + for (i = 0;
> + (i < nargs) && TYPE_CODE (t1[i].type) != TYPE_CODE_VOID;
> + i++)
> {
> struct type *tt1, *tt2;
> +
> if (!t2[i])
> return i + 1;
> - tt1 = check_typedef (t1[i]);
> +
> + tt1 = check_typedef (t1[i].type);
> tt2 = check_typedef (VALUE_TYPE (t2[i]));
> +
> if (TYPE_CODE (tt1) == TYPE_CODE_REF
> /* We should be doing hairy argument matching, as below. */
> && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1))) == TYPE_CODE (tt2)))
> @@ -2012,12 +1997,12 @@ typecmp (int staticp, struct type *t1[],
> /* We should be doing much hairier argument matching (see section 13.2
> of the ARM), but as a quick kludge, just check for the same type
> code. */
> - if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i])))
> + if (TYPE_CODE (t1[i].type) != TYPE_CODE (VALUE_TYPE (t2[i])))
> return i + 1;
> }
> - if (!t1[i])
> + if (varargs || t2[i] == NULL)
> return 0;
> - return t2[i] ? i + 1 : 0;
> + return i + 1;
> }
>
> /* Helper function used by value_struct_elt to recurse through baseclasses.
> @@ -2303,6 +2288,8 @@ search_struct_method (char *name, struct
> if (TYPE_FN_FIELD_STUB (f, j))
> check_stub_method (type, i, j);
> if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j),
> + TYPE_VARARGS (TYPE_FN_FIELD_TYPE (f, j)),
> + TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, j)),
> TYPE_FN_FIELD_ARGS (f, j), args))
> {
> if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
> @@ -2754,13 +2741,7 @@ find_overload_match (struct type **arg_t
> {
> if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
> static_offset = 1;
> - nparms=0;
> -
> - if (TYPE_FN_FIELD_ARGS(fns_ptr,ix))
> - {
> - while (TYPE_CODE(TYPE_FN_FIELD_ARGS(fns_ptr,ix)[nparms]) != TYPE_CODE_VOID)
> - nparms++;
> - }
> + nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
> }
> else
> {
> @@ -2772,7 +2753,7 @@ find_overload_match (struct type **arg_t
> parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *)));
> for (jj = 0; jj < nparms; jj++)
> parm_types[jj] = (method
> - ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj])
> + ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type)
> : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
>
> /* Compare parameter types to supplied argument types. Skip THIS for