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]

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


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