* 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.
+2002-06-14 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.
+
2002-06-13 Daniel Jacobowitz <drow@mvista.com>
* NEWS: Mention multithreaded debug support for gdbserver.
/* 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);
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, ")");
}
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)
{
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);
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 *,
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;
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
{
/* 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)
{
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);
TYPE_OBJFILE (type));
TYPE_TARGET_TYPE (mtype) = type;
/* _DOMAIN_TYPE (mtype) = unknown yet */
- /* _ARG_TYPES (mtype) = unknown yet */
return (mtype);
}
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;
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;
}
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. */
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. */
argcount = 0;
else
{
- argtypes[0] = lookup_pointer_type (type);
+ argtypes[0].type = lookup_pointer_type (type);
argcount = 1;
}
{
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;
}
}
}
- 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;
}
}
-/* 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);
}
}
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);
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);
#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)
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.
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;
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;
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. */
#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
#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)
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 *);
/* 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
{
/* 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;
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;
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 *,
{
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. */
++(*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;
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;
}
\f
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);
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
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)
}
\f
/* 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
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)))
/* 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.
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))
{
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
{
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