This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Switch TYPE_CODE_METHOD to store arguments like TYPE_CODE_FUNCTION


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]