From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2345 invoked by alias); 14 Jun 2002 01:10:28 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 2325 invoked from network); 14 Jun 2002 01:10:21 -0000 Received: from unknown (HELO zwingli.cygnus.com) (208.245.165.35) by sources.redhat.com with SMTP; 14 Jun 2002 01:10:21 -0000 Received: by zwingli.cygnus.com (Postfix, from userid 442) id DFF115EA11; Thu, 13 Jun 2002 20:10:19 -0500 (EST) To: Daniel Jacobowitz Cc: gdb-patches@sources.redhat.com Subject: Re: RFA: Switch TYPE_CODE_METHOD to store arguments like TYPE_CODE_FUNCTION References: <20020604024456.GA8733@branoic.them.org> From: Jim Blandy Date: Thu, 13 Jun 2002 18:10:00 -0000 In-Reply-To: <20020604024456.GA8733@branoic.them.org> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-06/txt/msg00237.txt.bz2 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 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 > > * 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, "", > 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