* debug.h (struct debug_write_fns): Remove ellipsis_type. Add int
authorIan Lance Taylor <ian@airs.com>
Fri, 19 Jan 1996 19:44:00 +0000 (19:44 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 19 Jan 1996 19:44:00 +0000 (19:44 +0000)
and boolean parameters to function_type.  Add boolean parameter to
method_type.
(debug_make_ellipsis_type): Don't declare.
(debug_make_function_type): Add debug_type * and boolean
parameters.  Change all callers.
(debug_make_method_type): Add boolean parameter.  Change all
callers.
(debug_get_parameter_types): Add boolean * parameter.  Change all
callers.
(debug_get_target_type): Declare.
* debug.c (struct debug_function_type): Add fields arg_types and
varargs.
(struct debug_method_type): Add field varargs.
(debug_ellipsis_type, ELLIPSIS_P): Remove.
(debug_make_ellipsis_type): Remove.
(debug_make_function_type): Add arg_types and varargs parameters.
(debug_make_method_type): Add varargs parameter.
(debug_get_parameter_types): Add pvarargs parameter.
(debug_get_target_type): New function.
(debug_write_type): In case DEBUG_KIND_FUNCTION, push argument
types and pass count to function_type.  In DEBUG_KIND_METHOD, use
a signed int for the count, don't call ellipsis_type, and pass
varargs to method_type.
* stabs.c (struct stab_demangle_info): Add varargs field.
(stab_demangle_argtypes): Add pvarargs parameter.  Change all
callers.
(stab_demangle_args): Likewise.
(stab_demangle_type): In case 'F', pick up argument types.
* prdbg.c (pr_ellipsis_type): Remove.
(pr_function_type): Add argcount and varargs parameters.
(pr_method_type): Add varargs parameter.
* ieee.c (ieee_ellipsis_type): Remove.
(ieee_function_type): Add argcount and varargs parameters.
(ieee_method_type): Add varargs parameter.  Remove most of
function body, and just call ieee_function_type.

binutils/ChangeLog
binutils/debug.c
binutils/debug.h
binutils/ieee.c
binutils/stabs.c

index f1754059926e9662bcada4a3e6bfe86cdcccafe8..c21f8f91f6721167b3d8e7878a0d602a7005aebb 100644 (file)
@@ -1,5 +1,42 @@
 Fri Jan 19 12:31:57 1996  Ian Lance Taylor  <ian@cygnus.com>
 
+       * debug.h (struct debug_write_fns): Remove ellipsis_type.  Add int
+       and boolean parameters to function_type.  Add boolean parameter to
+       method_type.
+       (debug_make_ellipsis_type): Don't declare.
+       (debug_make_function_type): Add debug_type * and boolean
+       parameters.  Change all callers.
+       (debug_make_method_type): Add boolean parameter.  Change all
+       callers.
+       (debug_get_parameter_types): Add boolean * parameter.  Change all
+       callers.
+       (debug_get_target_type): Declare.
+       * debug.c (struct debug_function_type): Add fields arg_types and
+       varargs.
+       (struct debug_method_type): Add field varargs.
+       (debug_ellipsis_type, ELLIPSIS_P): Remove.
+       (debug_make_ellipsis_type): Remove.
+       (debug_make_function_type): Add arg_types and varargs parameters.
+       (debug_make_method_type): Add varargs parameter.
+       (debug_get_parameter_types): Add pvarargs parameter.
+       (debug_get_target_type): New function.
+       (debug_write_type): In case DEBUG_KIND_FUNCTION, push argument
+       types and pass count to function_type.  In DEBUG_KIND_METHOD, use
+       a signed int for the count, don't call ellipsis_type, and pass
+       varargs to method_type.
+       * stabs.c (struct stab_demangle_info): Add varargs field.
+       (stab_demangle_argtypes): Add pvarargs parameter.  Change all
+       callers.
+       (stab_demangle_args): Likewise.
+       (stab_demangle_type): In case 'F', pick up argument types.
+       * prdbg.c (pr_ellipsis_type): Remove.
+       (pr_function_type): Add argcount and varargs parameters.
+       (pr_method_type): Add varargs parameter.
+       * ieee.c (ieee_ellipsis_type): Remove.
+       (ieee_function_type): Add argcount and varargs parameters.
+       (ieee_method_type): Add varargs parameter.  Remove most of
+       function body, and just call ieee_function_type.
+
        * stabs.c: Include "demangle.h".  Added several new static
        functions not listed below to demangle argument types; they are
        all called via stab_demangle_argtypes.
index edb5835c70d4d9242a126fa1c52ae5418a301875..0a6832ebda455ce1ea92fe1e463070936c342bdf 100644 (file)
@@ -184,6 +184,10 @@ struct debug_function_type
 {
   /* Return type.  */
   debug_type return_type;
+  /* NULL terminated array of argument types.  */
+  debug_type *arg_types;
+  /* Whether the function takes a variable number of arguments.  */
+  boolean varargs;
 };
 
 /* Information kept for a range.  */
@@ -244,6 +248,8 @@ struct debug_method_type
   debug_type domain_type;
   /* A NULL terminated array of argument types.  */
   debug_type *arg_types;
+  /* Whether the method takes a variable number of arguments.  */
+  boolean varargs;
 };
 
 /* Information kept for a named type.  */
@@ -503,15 +509,6 @@ struct debug_name
     } u;
 };
 
-/* This variable is an ellipsis type.  The contents are not used; its
-   address is returned by debug_make_ellipsis_type, and anything which
-   needs to know whether it is dealing with an ellipsis compares
-   addresses.  */
-
-static const struct debug_type debug_ellipsis_type;
-
-#define ELLIPSIS_P(t) ((t) == &debug_ellipsis_type)
-
 /* Local functions.  */
 
 static void debug_error PARAMS ((const char *));
@@ -1241,18 +1238,6 @@ debug_make_indirect_type (handle, slot, tag)
   return t;
 }
 
-/* Make an ellipsis type.  This is not a type at all, but is a marker
-   suitable for appearing in the list of argument types passed to
-   debug_make_method_type.  It should be used to indicate a method
-   which takes a variable number of arguments.  */
-
-debug_type
-debug_make_ellipsis_type (handle)
-     PTR handle;
-{
-  return (debug_type) &debug_ellipsis_type;
-}
-
 /* Make a void type.  There is only one of these.  */
 
 debug_type
@@ -1458,9 +1443,11 @@ debug_make_pointer_type (handle, type)
    to record the parameter types.  */
 
 debug_type
-debug_make_function_type (handle, type)
+debug_make_function_type (handle, type, arg_types, varargs)
      PTR handle;
      debug_type type;
+     debug_type *arg_types;
+     boolean varargs;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1477,6 +1464,8 @@ debug_make_function_type (handle, type)
   memset (f, 0, sizeof *f);
 
   f->return_type = type;
+  f->arg_types = arg_types;
+  f->varargs = varargs;
 
   t->u.kfunction = f;
 
@@ -1648,11 +1637,12 @@ debug_make_offset_type (handle, base_type, target_type)
    argument is a NULL terminated array of argument types.  */
 
 debug_type
-debug_make_method_type (handle, return_type, domain_type, arg_types)
+debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
      PTR handle;
      debug_type return_type;
      debug_type domain_type;
      debug_type *arg_types;
+     boolean varargs;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1671,6 +1661,7 @@ debug_make_method_type (handle, return_type, domain_type, arg_types)
   m->return_type = return_type;
   m->domain_type = domain_type;
   m->arg_types = arg_types;
+  m->varargs = varargs;
 
   t->u.kmethod = m;
 
@@ -2230,9 +2221,10 @@ debug_get_return_type (handle, type)
    we don't currently store the parameter types of a function).  */
 
 const debug_type *
-debug_get_parameter_types (handle, type)
+debug_get_parameter_types (handle, type, pvarargs)
      PTR handle;
      debug_type type;
+     boolean *pvarargs;
 {
   if (type == NULL)
     return NULL;
@@ -2242,11 +2234,38 @@ debug_get_parameter_types (handle, type)
     default:
       return NULL;
     case DEBUG_KIND_METHOD:
+      *pvarargs = type->u.kmethod->varargs;
       return type->u.kmethod->arg_types;
     }
   /*NOTREACHED*/
 }
 
+/* Get the target type of a type.  */
+
+debug_type
+debug_get_target_type (handle, type)
+     PTR handle;
+     debug_type type;
+{
+  if (type == NULL)
+    return NULL;
+  type = debug_get_real_type (handle, type);
+  switch (type->kind)
+    {
+    default:
+      return NULL;
+    case DEBUG_KIND_POINTER:
+      return type->u.kpointer;
+    case DEBUG_KIND_REFERENCE:
+      return type->u.kreference;
+    case DEBUG_KIND_CONST:
+      return type->u.kconst;
+    case DEBUG_KIND_VOLATILE:
+      return type->u.kvolatile;
+    }
+  /*NOTREACHED*/
+}
+
 /* Get the NULL terminated array of fields for a struct, union, or
    class.  */
 
@@ -2422,6 +2441,7 @@ debug_write_type (info, fns, fhandle, type, name)
      struct debug_name *name;
 {
   unsigned int i;
+  int is;
   const char *tag;
 
   /* If we have a name for this type, just output it.  We only output
@@ -2533,11 +2553,22 @@ debug_write_type (info, fns, fhandle, type, name)
        return false;
       return (*fns->pointer_type) (fhandle);
     case DEBUG_KIND_FUNCTION:
+      if (type->u.kfunction->arg_types == NULL)
+       is = -1;
+      else
+       {
+         for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
+           if (! debug_write_type (info, fns, fhandle,
+                                   type->u.kfunction->arg_types[is],
+                                   (struct debug_name *) NULL))
+             return false;
+       }
       if (! debug_write_type (info, fns, fhandle,
                              type->u.kfunction->return_type,
                              (struct debug_name *) NULL))
        return false;
-      return (*fns->function_type) (fhandle);
+      return (*fns->function_type) (fhandle, is,
+                                   type->u.kfunction->varargs);
     case DEBUG_KIND_REFERENCE:
       if (! debug_write_type (info, fns, fhandle, type->u.kreference,
                              (struct debug_name *) NULL))
@@ -2578,24 +2609,14 @@ debug_write_type (info, fns, fhandle, type, name)
                              (struct debug_name *) NULL))
        return false;
       if (type->u.kmethod->arg_types == NULL)
-       i = -1;
+       is = -1;
       else
        {
-         for (i = 0; type->u.kmethod->arg_types[i] != NULL; i++)
-           {
-             if (ELLIPSIS_P (type->u.kmethod->arg_types[i]))
-               {
-                 if (! (*fns->ellipsis_type) (fhandle))
-                   return false;
-               }
-             else
-               {
-                 if (! debug_write_type (info, fns, fhandle,
-                                         type->u.kmethod->arg_types[i],
-                                         (struct debug_name *) NULL))
-                   return false;
-               }
-           }
+         for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
+           if (! debug_write_type (info, fns, fhandle,
+                                   type->u.kmethod->arg_types[is],
+                                   (struct debug_name *) NULL))
+             return false;
        }
       if (type->u.kmethod->domain_type != NULL)
        {
@@ -2606,7 +2627,8 @@ debug_write_type (info, fns, fhandle, type, name)
        }
       return (*fns->method_type) (fhandle,
                                  type->u.kmethod->domain_type != NULL,
-                                 i);
+                                 is,
+                                 type->u.kmethod->varargs);
     case DEBUG_KIND_CONST:
       if (! debug_write_type (info, fns, fhandle, type->u.kconst,
                              (struct debug_name *) NULL))
index d40679bb57b8344c2b5d0508ace12cad301ae64e..38ef7892867bb3ae89f973d1c7afaedf6131ea89 100644 (file)
@@ -174,11 +174,6 @@ struct debug_write_fns
 
   /* Each writer must keep a stack of types.  */
 
-  /* Push an ellipsis type onto the type stack.  This is not a real
-     type, but is used when a method takes a variable number of
-     arguments.  */
-  boolean (*ellipsis_type) PARAMS ((PTR));
-
   /* Push an empty type onto the type stack.  This type can appear if
      there is a reference to a type which is never defined.  */
   boolean (*empty_type) PARAMS ((PTR));
@@ -210,9 +205,15 @@ struct debug_write_fns
      type onto the type stack.  */
   boolean (*pointer_type) PARAMS ((PTR));
 
-  /* Pop the top type on the type stack, and push a function returning
-     that type onto the type stack.  */
-  boolean (*function_type) PARAMS ((PTR));
+  /* Push a function type onto the type stack.  The second argument
+     indicates the number of argument types that have been pushed onto
+     the stack.  If the number of argument types is passed as -1, then
+     the argument types of the function are unknown, and no types have
+     been pushed onto the stack.  The third argument is true if the
+     function takes a variable number of arguments.  The return type
+     of the function is pushed onto the type stack below the argument
+     types, if any.  */
+  boolean (*function_type) PARAMS ((PTR, int, boolean));
 
   /* Pop the top type on the type stack, and push a reference to that
      type onto the type stack.  */
@@ -247,12 +248,13 @@ struct debug_write_fns
      class to which the method is attached.  The third argument is the
      number of argument types; these are pushed onto the type stack in
      reverse order (the first type popped is the last argument to the
-     method).  An argument type of -1 means that no argument in
-     formation is available.  The next type on the type stack below
-     the domain and the argument types is the return type of the
-     method.  All these types must be popped, and then the method type
-     must be pushed.  */
-  boolean (*method_type) PARAMS ((PTR, boolean, int));
+     method).  A value of -1 for the third argument means that no
+     argument information is available.  The fourth argument is true
+     if the function takes a variable number of arguments.  The next
+     type on the type stack below the domain and the argument types is
+     the return type of the method.  All these types must be popped,
+     and then the method type must be pushed.  */
+  boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
 
   /* Pop the top type off the type stack, and push a const qualified
      version of that type onto the type stack.  */
@@ -519,13 +521,6 @@ extern boolean debug_record_variable
 extern debug_type debug_make_indirect_type
   PARAMS ((PTR, debug_type *, const char *));
 
-/* Make an ellipsis type.  This is not a type at all, but is a marker
-   suitable for appearing in the list of argument types passed to
-   debug_make_method_type.  It should be used to indicate a method
-   which takes a variable number of arguments.  */
-
-extern debug_type debug_make_ellipsis_type PARAMS ((PTR));
-
 /* Make a void type.  */
 
 extern debug_type debug_make_void_type PARAMS ((PTR));
@@ -578,10 +573,14 @@ extern debug_type debug_make_enum_type
 extern debug_type debug_make_pointer_type
   PARAMS ((PTR, debug_type));
 
-/* Make a function returning a given type.  FIXME: We should be able
-   to record the parameter types.  */
+/* Make a function type.  The second argument is the return type.  The
+   third argument is a NULL terminated array of argument types.  The
+   fourth argument is true if the function takes a variable number of
+   arguments.  If the third argument is NULL, then the argument types
+   are unknown.  */
 
-extern debug_type debug_make_function_type PARAMS ((PTR, debug_type));
+extern debug_type debug_make_function_type
+  PARAMS ((PTR, debug_type, debug_type *, boolean));
 
 /* Make a reference to a given type.  */
 
@@ -618,14 +617,17 @@ extern debug_type debug_make_offset_type
   PARAMS ((PTR, debug_type, debug_type));
 
 /* Make a type for a method function.  The second argument is the
-   return type, the third argument is the domain, and the fourth
-   argument is a NULL terminated array of argument types.  The domain
-   and the argument array may be NULL, in which case this is a stub
-   method and that information is not available.  Stabs debugging uses
-   this, and gets the argument types from the mangled name.  */
+   return type.  The third argument is the domain.  The fourth
+   argument is a NULL terminated array of argument types.  The fifth
+   argument is true if the function takes a variable number of
+   arguments, in which case the array of argument types indicates the
+   types of the first arguments.  The domain and the argument array
+   may be NULL, in which case this is a stub method and that
+   information is not available.  Stabs debugging uses this, and gets
+   the argument types from the mangled name.  */
 
 extern debug_type debug_make_method_type
-  PARAMS ((PTR, debug_type, debug_type, debug_type *));
+  PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
 
 /* Make a const qualified version of a given type.  */
 
@@ -738,9 +740,18 @@ extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
 /* Get the NULL terminated array of parameter types for a function or
    method type (actually, parameter types are not currently stored for
    function types).  This may be used to determine whether a method
-   type is a stub method or not.  */
+   type is a stub method or not.  The last argument points to a
+   boolean which is set to true if the function takes a variable
+   number of arguments.  */
+
+extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
+                                                           debug_type,
+                                                           boolean *));
+
+/* Get the target type of a pointer or reference or const or volatile
+   type.  */
 
-extern const debug_type *debug_get_parameter_types PARAMS ((PTR, debug_type));
+extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
 
 /* Get the NULL terminated array of fields for a struct, union, or
    class.  */
index 0006460b4cc60ba32dbdb9c3982574de7544903e..8f0407b3882d3c31620902441a43d0af07eb5417 100644 (file)
@@ -1664,7 +1664,8 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
          }
        while (present);
 
-       type = debug_make_function_type (dhandle, rtype);
+       type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
+                                        false);
        return_type = rtype;
       }
       break;
@@ -1779,6 +1780,8 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
       {
        bfd_vma attr, frame_type, push_mask, nargs, level, father;
        debug_type rtype;
+       debug_type *arg_types;
+       boolean varargs;
        boolean present;
 
        /* FIXME: We ignore almost all this information.  */
@@ -1790,23 +1793,49 @@ parse_ieee_ty (dhandle, abfd, types, vars, bytes, pp, pend)
                                       &rtype)
            || ! ieee_read_number (abfd, bytes, pp, pend, &nargs))
          return false;
-       if (nargs != (bfd_vma) -1)
+       if (nargs == (bfd_vma) -1)
          {
-           for (; nargs > 0; nargs--)
-             {
-               debug_type atype;
+           arg_types = NULL;
+           varargs = false;
+         }
+       else
+         {
+           unsigned int i;
 
-               if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp,
-                                           pend, &atype))
-                 return false;
+           arg_types = ((debug_type *)
+                        xmalloc ((nargs + 1) * sizeof *arg_types));
+           for (i = 0; i < nargs; i++)
+             if (! ieee_read_type_index (dhandle, abfd, types, bytes, pp,
+                                         pend, arg_types + i))
+               return false;
+
+           /* If the last type is pointer to void, this is really a
+               varargs function.  */
+           varargs = false;
+           if (nargs > 0)
+             {
+               debug_type last;
+
+               last = arg_types[nargs - 1];
+               if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
+                   && (debug_get_type_kind (dhandle,
+                                            debug_get_target_type (dhandle,
+                                                                   last))
+                       == DEBUG_KIND_VOID))
+                 {
+                   --nargs;
+                   varargs = true;
+                 }
              }
+
+           arg_types[nargs] = DEBUG_TYPE_NULL;
          }
        if (! ieee_read_number (abfd, bytes, pp, pend, &level)
            || ! ieee_read_optional_number (abfd, bytes, pp, pend, &father,
                                            &present))
          return false;
 
-       type = debug_make_function_type (dhandle, rtype);
+       type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
        return_type = rtype;
       }
       break;
@@ -2357,7 +2386,6 @@ static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
 
 static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
 static boolean ieee_start_source PARAMS ((PTR, const char *));
-static boolean ieee_ellipsis_type PARAMS ((PTR));
 static boolean ieee_empty_type PARAMS ((PTR));
 static boolean ieee_void_type PARAMS ((PTR));
 static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
@@ -2367,14 +2395,14 @@ static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
 static boolean ieee_enum_type
   PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
 static boolean ieee_pointer_type PARAMS ((PTR));
-static boolean ieee_function_type PARAMS ((PTR));
+static boolean ieee_function_type PARAMS ((PTR, int, boolean));
 static boolean ieee_reference_type PARAMS ((PTR));
 static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
 static boolean ieee_array_type
   PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
 static boolean ieee_set_type PARAMS ((PTR, boolean));
 static boolean ieee_offset_type PARAMS ((PTR));
-static boolean ieee_method_type PARAMS ((PTR, boolean, int));
+static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
 static boolean ieee_const_type PARAMS ((PTR));
 static boolean ieee_volatile_type PARAMS ((PTR));
 static boolean ieee_start_struct_type
@@ -2420,7 +2448,6 @@ static const struct debug_write_fns ieee_fns =
 {
   ieee_start_compilation_unit,
   ieee_start_source,
-  ieee_ellipsis_type,
   ieee_empty_type,
   ieee_void_type,
   ieee_int_type,
@@ -3161,15 +3188,6 @@ ieee_start_source (p, filename)
   return true;
 }
 
-/* Make an ellipsis type.  */
-
-static boolean
-ieee_ellipsis_type (p)
-     PTR p;
-{
-  abort ();
-}
-
 /* Make an empty type.  */
 
 static boolean
@@ -3382,27 +3400,53 @@ ieee_pointer_type (p)
 /* Make a function type.  */
 
 static boolean
-ieee_function_type (p)
+ieee_function_type (p, argcount, varargs)
      PTR p;
+     int argcount;
+     boolean varargs;
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
-  unsigned int indx;
+  unsigned int *args = NULL;
+  int i;
+  unsigned int retindx;
 
-  indx = ieee_pop_type (info);
+  if (argcount > 0)
+    {
+      args = (unsigned int *) xmalloc (argcount * sizeof *args);
+      for (i = argcount - 1; i >= 0; i--)
+       args[i] = ieee_pop_type (info);
+    }
+  else if (argcount < 0)
+    varargs = false;
 
-  /* FIXME: IEEE can represent the argument types for the function,
-     but we didn't store them.  */
+  retindx = ieee_pop_type (info);
 
   /* An attribute of 0x41 means that the frame and push mask are
      unknown.  */
-  return (ieee_define_type (info, 0, true)
-         && ieee_write_number (info, 'x')
-         && ieee_write_number (info, 0x41)
-         && ieee_write_number (info, 0)
-         && ieee_write_number (info, 0)
-         && ieee_write_number (info, indx)
-         && ieee_write_number (info, (bfd_vma) -1)
-         && ieee_write_number (info, 0));
+  if (! ieee_define_type (info, 0, true)
+      || ! ieee_write_number (info, 'x')
+      || ! ieee_write_number (info, 0x41)
+      || ! ieee_write_number (info, 0)
+      || ! ieee_write_number (info, 0)
+      || ! ieee_write_number (info, retindx)
+      || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
+    return false;
+  if (argcount > 0)
+    {
+      for (i = 0; i < argcount; i++)
+       if (! ieee_write_number (info, args[i]))
+         return false;
+      free (args);
+    }
+  if (varargs)
+    {
+      /* A varargs function is represented by writing out the last
+         argument as type void *, although this makes little sense.  */
+      if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
+       return false;
+    }
+
+  return ieee_write_number (info, 0);
 }
 
 /* Make a reference type.  */
@@ -3520,15 +3564,13 @@ ieee_offset_type (p)
 /* Make a method type.  */
 
 static boolean
-ieee_method_type (p, domain, argcount)
+ieee_method_type (p, domain, argcount, varargs)
      PTR p;
      boolean domain;
      int argcount;
+     boolean varargs;
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
-  unsigned int *args = NULL;
-  int i;
-  unsigned int retindx;
 
   /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
      method, but the definition is incomplete.  We just output an 'x'
@@ -3537,32 +3579,7 @@ ieee_method_type (p, domain, argcount)
   if (domain)
     (void) ieee_pop_type (info);
 
-  if (argcount > 0)
-    {
-      args = (unsigned int *) xmalloc (argcount * sizeof *args);
-      for (i = argcount - 1; i >= 0; i--)
-       args[i] = ieee_pop_type (info);
-    }
-
-  retindx = ieee_pop_type (info);
-
-  if (! ieee_define_type (info, 0, true)
-      || ! ieee_write_number (info, 'x')
-      || ! ieee_write_number (info, 0x41)
-      || ! ieee_write_number (info, 0)
-      || ! ieee_write_number (info, 0)
-      || ! ieee_write_number (info, retindx)
-      || ! ieee_write_number (info, (bfd_vma) argcount))
-    return false;
-  if (argcount > 0)
-    {
-      for (i = 0; i < argcount; i++)
-       if (! ieee_write_number (info, args[i]))
-         return false;
-      free (args);
-    }
-
-  return ieee_write_number (info, 0);
+  return ieee_function_type (p, argcount, varargs);
 }
 
 /* Make a const qualified type.  */
index 76b221b0f4acb85c4883795d06b17d2e2172d4ab..be9fce0a6f21cdfd42f0a61100e22aab7858c5d1 100644 (file)
@@ -193,7 +193,7 @@ static debug_type stab_find_tagged_type
   PARAMS ((PTR, struct stab_handle *, const char *, int,
           enum debug_type_kind));
 static debug_type *stab_demangle_argtypes
-  PARAMS ((PTR, struct stab_handle *, const char *));
+  PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
 
 /* Save a string in memory.  */
 
@@ -827,9 +827,13 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
          dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                                   (debug_type **) NULL);
          if (dtype != DEBUG_TYPE_NULL)
-           dtype = debug_make_pointer_type (dhandle,
-                                            debug_make_function_type (dhandle,
-                                                                      dtype));
+           {
+             debug_type ftype;
+
+             ftype = debug_make_function_type (dhandle, dtype,
+                                               (debug_type *) NULL, false);
+             dtype = debug_make_pointer_type (dhandle, ftype);
+           }
        }
       if (dtype == DEBUG_TYPE_NULL)
        return false;
@@ -1278,7 +1282,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
       dtype = (debug_make_function_type
               (dhandle,
                parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                (debug_type **) NULL)));
+                                (debug_type **) NULL),
+               (debug_type *) NULL, false));
       break;
 
     case 'k':
@@ -1348,7 +1353,8 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
            }
          ++*pp;
          dtype = debug_make_method_type (dhandle, return_type,
-                                         DEBUG_TYPE_NULL, NULL);
+                                         DEBUG_TYPE_NULL,
+                                         (debug_type *) NULL, false);
        }
       else
        {
@@ -1357,6 +1363,7 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
          debug_type *args;
          unsigned int n;
          unsigned int alloc;
+         boolean varargs;
 
          domain = parse_stab_type (dhandle, info, (const char *) NULL,
                                    pp, (debug_type **) NULL);
@@ -1402,30 +1409,22 @@ parse_stab_type (dhandle, info, typename, pp, slotp)
            }
          ++*pp;
 
-         /* If the last type is void, then this function does not
-            take a variable number of arguments.  If the last is not
-            void, then it does.  */
-         if (n > 0
-             && debug_get_type_kind (dhandle, args[n - 1]) == DEBUG_KIND_VOID)
-           --n;
+         /* If the last type is not void, then this function takes a
+            variable number of arguments.  Otherwise, we must strip
+            the void type.  */
+         if (n == 0
+             || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
+           varargs = true;
          else
            {
-             if (n + 1 >= alloc)
-               {
-                 alloc += 10;
-                 args = ((debug_type *)
-                         xrealloc ((PTR) args, alloc * sizeof *args));
-               }
-
-             args[n] = debug_make_ellipsis_type (dhandle);
-             if (args[n] == DEBUG_TYPE_NULL)
-               return DEBUG_TYPE_NULL;
-             ++n;
+             --n;
+             varargs = false;
            }
 
          args[n] = DEBUG_TYPE_NULL;
 
-         dtype = debug_make_method_type (dhandle, return_type, domain, args);
+         dtype = debug_make_method_type (dhandle, return_type, domain, args,
+                                         varargs);
        }
       break;
 
@@ -2499,6 +2498,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
          bfd_vma voffset;
          debug_type context;
          const char *physname;
+         boolean varargs;
 
          if (look_ahead_type != DEBUG_TYPE_NULL)
            {
@@ -2661,7 +2661,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
             and the argument types, must be deduced from it.  */
 
          if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
-             && debug_get_parameter_types (dhandle, type) != NULL)
+             && debug_get_parameter_types (dhandle, type, &varargs) != NULL)
            physname = argtypes;
          else
            {
@@ -2759,6 +2759,7 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
   boolean is_constructor;
   boolean is_destructor;
   debug_type *args;
+  boolean varargs;
 
   /* Constructors are sometimes handled specially.  */
   is_full_physname_constructor = ((argtypes[0] == '_'
@@ -2847,14 +2848,16 @@ parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
     {
       args = (debug_type *) xmalloc (sizeof *args);
       *args = NULL;
-      return debug_make_method_type (dhandle, return_type, class_type, args);
+      return debug_make_method_type (dhandle, return_type, class_type, args,
+                                    false);
     }
 
-  args = stab_demangle_argtypes (dhandle, info, *pphysname);
+  args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
   if (args == NULL)
     return DEBUG_TYPE_NULL;
 
-  return debug_make_method_type (dhandle, return_type, class_type, args);
+  return debug_make_method_type (dhandle, return_type, class_type, args,
+                                varargs);
 }
 
 /* The tail end of stabs for C++ classes that contain a virtual function
@@ -3492,6 +3495,8 @@ struct stab_demangle_info
   struct stab_handle *info;
   /* The array of arguments we are building.  */
   debug_type *args;
+  /* Whether the method takes a variable number of arguments.  */
+  boolean varargs;
   /* The array of types we have remembered.  */
   struct stab_demangle_typestring *typestrings;
   /* The number of typestrings.  */
@@ -3517,7 +3522,8 @@ static boolean stab_demangle_template
 static boolean stab_demangle_class
   PARAMS ((struct stab_demangle_info *, const char **, const char **));
 static boolean stab_demangle_args
-  PARAMS ((struct stab_demangle_info *, const char **, debug_type **));
+  PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+          boolean *));
 static boolean stab_demangle_arg
   PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
           unsigned int *, unsigned int *));
@@ -3596,16 +3602,18 @@ stab_demangle_get_count (pp, pi)
    terminated array of argument types.  */
 
 static debug_type *
-stab_demangle_argtypes (dhandle, info, physname)
+stab_demangle_argtypes (dhandle, info, physname, pvarargs)
      PTR dhandle;
      struct stab_handle *info;
      const char *physname;
+     boolean *pvarargs;
 {
   struct stab_demangle_info minfo;
 
   minfo.dhandle = dhandle;
   minfo.info = info;
   minfo.args = NULL;
+  minfo.varargs = false;
   minfo.typestring_alloc = 10;
   minfo.typestrings = ((struct stab_demangle_typestring *)
                       xmalloc (minfo.typestring_alloc
@@ -3630,6 +3638,7 @@ stab_demangle_argtypes (dhandle, info, physname)
   if (minfo.args == NULL)
     fprintf (stderr, "no argument types in mangled string\n");
 
+  *pvarargs = minfo.varargs;
   return minfo.args;
 
  error_return:
@@ -3820,7 +3829,7 @@ stab_demangle_signature (minfo, pp)
          hold = NULL;
          func_done = true;
          ++*pp;
-         if (! stab_demangle_args (minfo, pp, &minfo->args))
+         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
            return false;
          break;
 
@@ -3848,7 +3857,7 @@ stab_demangle_signature (minfo, pp)
          /* Assume we have stumbled onto the first outermost function
             argument token, and start processing args.  */
          func_done = true;
-         if (! stab_demangle_args (minfo, pp, &minfo->args))
+         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
            return false;
          break;
        }
@@ -3856,7 +3865,7 @@ stab_demangle_signature (minfo, pp)
       if (expect_func)
        {
          func_done = true;
-         if (! stab_demangle_args (minfo, pp, &minfo->args))
+         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
            return false;
        }
     }
@@ -3867,7 +3876,7 @@ stab_demangle_signature (minfo, pp)
         bar__3fooi is 'foo::bar(int)'.  We get here when we find the
         first case, and need to ensure that the '(void)' gets added
         to the current declp.  */
-      if (! stab_demangle_args (minfo, pp, &minfo->args))
+      if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
        return false;
     }
 
@@ -4250,10 +4259,11 @@ stab_demangle_class (minfo, pp, pstart)
    is set to a NULL terminated array holding the arguments.  */
 
 static boolean
-stab_demangle_args (minfo, pp, pargs)
+stab_demangle_args (minfo, pp, pargs, pvarargs)
      struct stab_demangle_info *minfo;
      const char **pp;
      debug_type **pargs;
+     boolean *pvarargs;
 {
   const char *orig;
   unsigned int alloc, count;
@@ -4262,7 +4272,10 @@ stab_demangle_args (minfo, pp, pargs)
 
   alloc = 10;
   if (pargs != NULL)
-    *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+    {
+      *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+      *pvarargs = false;
+    }
   count = 0;
 
   while (**pp != '_' && **pp != '\0' && **pp != 'e')
@@ -4313,32 +4326,16 @@ stab_demangle_args (minfo, pp, pargs)
        }
     }
 
+  if (pargs != NULL)
+    (*pargs)[count] = DEBUG_TYPE_NULL;
+
   if (**pp == 'e')
     {
       if (pargs != NULL)
-       {
-         debug_type type;
-
-         type = debug_make_ellipsis_type (minfo->dhandle);
-         if (type == DEBUG_TYPE_NULL)
-           return false;
-
-         if (count + 1 >= alloc)
-           {
-             alloc += 10;
-             *pargs = ((debug_type *)
-                       xrealloc (*pargs, alloc * sizeof **pargs));
-           }
-         (*pargs)[count] = type;
-         ++count;
-       }
-
+       *pvarargs = true;
       ++*pp;
     }
 
-  if (pargs != NULL)
-    (*pargs)[count] = DEBUG_TYPE_NULL;
-
   return true;
 }
 
@@ -4478,23 +4475,35 @@ stab_demangle_type (minfo, pp, ptype)
 
     case 'F':
       /* A function.  */
-      ++*pp;
-      /* FIXME: We should pick up the argument types.  */
-      if (! stab_demangle_args (minfo, pp, (debug_type **) NULL))
-       return false;
-      if (**pp != '_')
-       {
-         /* cplus_demangle will accept a function without a return
-             type, but I don't know when that will happen, or what to
-             do if it does.  */
-         stab_bad_demangle (orig);
+      {
+       debug_type *args;
+       boolean varargs;
+
+       ++*pp;
+       if (! stab_demangle_args (minfo, pp,
+                                 (ptype == NULL
+                                  ? (debug_type **) NULL
+                                  : &args),
+                                 (ptype == NULL
+                                  ? (boolean *) NULL
+                                  : &varargs)))
          return false;
-       }
-      ++*pp;
-      if (! stab_demangle_type (minfo, pp, ptype))
-       return false;
-      if (ptype != NULL)
-       *ptype = debug_make_function_type (minfo->dhandle, *ptype);
+       if (**pp != '_')
+         {
+           /* cplus_demangle will accept a function without a return
+              type, but I don't know when that will happen, or what
+              to do if it does.  */
+           stab_bad_demangle (orig);
+           return false;
+         }
+       ++*pp;
+       if (! stab_demangle_type (minfo, pp, ptype))
+         return false;
+       if (ptype != NULL)
+         *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
+                                            varargs);
+
+      }
       break;
 
     case 'M':
@@ -4502,6 +4511,7 @@ stab_demangle_type (minfo, pp, ptype)
       {
        boolean memberp, constp, volatilep;
        debug_type *args;
+       boolean varargs;
        unsigned int n;
        const char *name;
 
@@ -4509,6 +4519,7 @@ stab_demangle_type (minfo, pp, ptype)
        constp = false;
        volatilep = false;
        args = NULL;
+       varargs = false;
 
        ++*pp;
        if (! isdigit ((unsigned char) **pp))
@@ -4546,7 +4557,10 @@ stab_demangle_type (minfo, pp, ptype)
            if (! stab_demangle_args (minfo, pp,
                                      (ptype == NULL
                                       ? (debug_type **) NULL
-                                      : &args)))
+                                      : &args),
+                                     (ptype == NULL
+                                      ? (boolean *) NULL
+                                      : &varargs)))
              return false;
          }
 
@@ -4578,7 +4592,7 @@ stab_demangle_type (minfo, pp, ptype)
                /* FIXME: We have no way to record constp or
                    volatilep.  */
                *ptype = debug_make_method_type (minfo->dhandle, *ptype,
-                                                class_type, args);
+                                                class_type, args, varargs);
              }
          }
       }