This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
RFA: Switch TYPE_CODE_METHOD to store arguments like TYPE_CODE_FUNCTION
- From: Daniel Jacobowitz <drow at mvista dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 3 Jun 2002 22:44:57 -0400
- Subject: RFA: Switch TYPE_CODE_METHOD to store arguments like TYPE_CODE_FUNCTION
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