* mips-dis.c: Add missing prototypes.
[deliverable/binutils-gdb.git] / binutils / ieee.c
index 642006b27297fe683494ec5ca5a2ffc46ec12627..ad5ddc7d65cb3aed0b6adcd83e4d2703fb3b7ae6 100644 (file)
@@ -1,5 +1,5 @@
 /* ieee.c -- Read and write IEEE-695 debugging information.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
@@ -30,6 +30,7 @@
 #include "libiberty.h"
 #include "debug.h"
 #include "budbg.h"
+#include "filenames.h"
 
 /* This structure holds an entry on the block stack.  */
 
@@ -41,6 +42,8 @@ struct ieee_block
   const char *filename;
   /* The index of the function type, for a BB4 or BB6 block.  */
   unsigned int fnindx;
+  /* True if this function is being skipped.  */
+  boolean skip;
 };
 
 /* This structure is the block stack.  */
@@ -152,10 +155,16 @@ struct ieee_info
   const bfd_byte *pend;
   /* The block stack.  */
   struct ieee_blockstack blockstack;
+  /* Whether we have seen a BB1 or BB2.  */
+  boolean saw_filename;
   /* The variables.  */
   struct ieee_vars vars;
+  /* The global variables, after a global typedef block.  */
+  struct ieee_vars *global_vars;
   /* The types.  */
   struct ieee_types types;
+  /* The global types, after a global typedef block.  */
+  struct ieee_types *global_types;
   /* The list of tagged structs.  */
   struct ieee_tag *tags;
 };
@@ -305,7 +314,7 @@ ieee_eof (info)
      struct ieee_info *info;
 {
   ieee_error (info, (const bfd_byte *) NULL,
-             "unexpected end of debugging information");
+             _("unexpected end of debugging information"));
 }
 
 /* Save a string in memory.  */
@@ -400,8 +409,8 @@ ieee_read_optional_number (info, pp, pv, ppresent)
       return true;
     }
 
-  ieee_error (info, *pp - 1, "invalid number");
-  return false;  
+  ieee_error (info, *pp - 1, _("invalid number"));
+  return false;
 }
 
 /* Read a required string from an IEEE file.  */
@@ -459,7 +468,7 @@ ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
          *ppresent = false;
          return true;
        }
-      ieee_error (info, *pp - 1, "invalid string length");
+      ieee_error (info, *pp - 1, _("invalid string length"));
       return false;
     }
 
@@ -516,7 +525,7 @@ ieee_read_expression (info, pp, pv)
        {
          if (esp - expr_stack >= EXPR_STACK_SIZE)
            {
-             ieee_error (info, start, "expression stack overflow");
+             ieee_error (info, start, _("expression stack overflow"));
              return false;
            }
          *esp++ = val;
@@ -536,7 +545,7 @@ ieee_read_expression (info, pp, pv)
       switch (c)
        {
        default:
-         ieee_error (info, start, "unsupported IEEE expression operator");
+         ieee_error (info, start, _("unsupported IEEE expression operator"));
          break;
 
        case ieee_variable_R_enum:
@@ -551,13 +560,13 @@ ieee_read_expression (info, pp, pv)
                break;
            if (s == NULL)
              {
-               ieee_error (info, start, "unknown section");
+               ieee_error (info, start, _("unknown section"));
                return false;
              }
-           
+
            if (esp - expr_stack >= EXPR_STACK_SIZE)
              {
-               ieee_error (info, start, "expression stack overflow");
+               ieee_error (info, start, _("expression stack overflow"));
                return false;
              }
 
@@ -572,7 +581,7 @@ ieee_read_expression (info, pp, pv)
 
            if (esp - expr_stack < 2)
              {
-               ieee_error (info, start, "expression stack underflow");
+               ieee_error (info, start, _("expression stack underflow"));
                return false;
              }
 
@@ -586,7 +595,7 @@ ieee_read_expression (info, pp, pv)
 
   if (esp - 1 != expr_stack)
     {
-      ieee_error (info, expr_start, "expression stack mismatch");
+      ieee_error (info, expr_start, _("expression stack mismatch"));
       return false;
     }
 
@@ -625,7 +634,7 @@ ieee_builtin_type (info, p, indx)
   switch ((enum builtin_types) indx)
     {
     default:
-      ieee_error (info, p, "unknown builtin type");
+      ieee_error (info, p, _("unknown builtin type"));
       return NULL;
 
     case builtin_unknown:
@@ -770,8 +779,8 @@ ieee_builtin_type (info, p, indx)
       break;
 
     case builtin_bcd_float:
-      ieee_error (info, p, "BCD float type not supported");
-      return false;
+      ieee_error (info, p, _("BCD float type not supported"));
+      return DEBUG_TYPE_NULL;
     }
 
   if (name != NULL)
@@ -889,10 +898,13 @@ parse_ieee (dhandle, abfd, bytes, len)
   info.bytes = bytes;
   info.pend = bytes + len;
   info.blockstack.bsp = info.blockstack.stack;
+  info.saw_filename = false;
   info.vars.alloc = 0;
   info.vars.vars = NULL;
+  info.global_vars = NULL;
   info.types.alloc = 0;
   info.types.types = NULL;
+  info.global_types = NULL;
   info.tags = NULL;
   for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
     info.types.builtins[i] = DEBUG_TYPE_NULL;
@@ -913,14 +925,14 @@ parse_ieee (dhandle, abfd, bytes, len)
 
       if (c <= ieee_number_repeat_end_enum)
        {
-         ieee_error (&info, record_start, "unexpected number");
+         ieee_error (&info, record_start, _("unexpected number"));
          return false;
        }
 
       switch (c)
        {
        default:
-         ieee_error (&info, record_start, "unexpected record type");
+         ieee_error (&info, record_start, _("unexpected record type"));
          return false;
 
        case ieee_bb_record_enum:
@@ -953,7 +965,7 @@ parse_ieee (dhandle, abfd, bytes, len)
   if (info.blockstack.bsp != info.blockstack.stack)
     {
       ieee_error (&info, (const bfd_byte *) NULL,
-                 "blocks left on stack at end");
+                 _("blocks left on stack at end"));
       return false;
     }
 
@@ -972,8 +984,9 @@ parse_ieee_bb (info, pp)
   bfd_vma size;
   const char *name;
   unsigned long namlen;
-  char *namcopy;
+  char *namcopy = NULL;
   unsigned int fnindx;
+  boolean skip;
 
   block_start = *pp;
 
@@ -985,6 +998,7 @@ parse_ieee_bb (info, pp)
     return false;
 
   fnindx = (unsigned int) -1;
+  skip = false;
 
   switch (b)
     {
@@ -995,6 +1009,29 @@ parse_ieee_bb (info, pp)
        return false;
       if (! debug_set_filename (info->dhandle, namcopy))
        return false;
+      info->saw_filename = true;
+
+      /* Discard any variables or types we may have seen before.  */
+      if (info->vars.vars != NULL)
+       free (info->vars.vars);
+      info->vars.vars = NULL;
+      info->vars.alloc = 0;
+      if (info->types.types != NULL)
+       free (info->types.types);
+      info->types.types = NULL;
+      info->types.alloc = 0;
+
+      /* Initialize the types to the global types.  */
+      if (info->global_types != NULL)
+       {
+         info->types.alloc = info->global_types->alloc;
+         info->types.types = ((struct ieee_type *)
+                              xmalloc (info->types.alloc
+                                       * sizeof (*info->types.types)));
+         memcpy (info->types.types, info->global_types->types,
+                 info->types.alloc * sizeof (*info->types.types));
+       }
+
       break;
 
     case 2:
@@ -1002,6 +1039,7 @@ parse_ieee_bb (info, pp)
         empty, but we don't check. */
       if (! debug_set_filename (info->dhandle, "*global*"))
        return false;
+      info->saw_filename = true;
       break;
 
     case 3:
@@ -1098,40 +1136,51 @@ parse_ieee_bb (info, pp)
          }
        else
          {
-           debug_type return_type;
-
-           if (typindx < 256)
-             {
-               return_type = ieee_builtin_type (info, block_start, typindx);
-               if (return_type == NULL)
-                 return false;
-             }
+           /* The MRI C++ compiler will output a fake function named
+              __XRYCPP to hold C++ debugging information.  We skip
+              that function.  This is not crucial, but it makes
+              converting from IEEE to other debug formats work
+              better.  */
+           if (strncmp (name, "__XRYCPP", namlen) == 0)
+             skip = true;
            else
              {
-               typindx -= 256;
-               if (! ieee_alloc_type (info, typindx, true))
+               debug_type return_type;
+
+               if (typindx < 256)
+                 {
+                   return_type = ieee_builtin_type (info, block_start,
+                                                    typindx);
+                   if (return_type == NULL)
+                     return false;
+                 }
+               else
+                 {
+                   typindx -= 256;
+                   if (! ieee_alloc_type (info, typindx, true))
+                     return false;
+                   fnindx = typindx;
+                   return_type = info->types.types[typindx].type;
+                   if (debug_get_type_kind (info->dhandle, return_type)
+                       == DEBUG_KIND_FUNCTION)
+                     return_type = debug_get_return_type (info->dhandle,
+                                                          return_type);
+                 }
+
+               namcopy = savestring (name, namlen);
+               if (namcopy == NULL)
+                 return false;
+               if (! debug_record_function (info->dhandle, namcopy,
+                                            return_type, false, offset))
                  return false;
-               fnindx = typindx;
-               return_type = info->types.types[typindx].type;
-               if (debug_get_type_kind (info->dhandle, return_type)
-                   == DEBUG_KIND_FUNCTION)
-                 return_type = debug_get_return_type (info->dhandle,
-                                                      return_type);
              }
-
-           namcopy = savestring (name, namlen);
-           if (namcopy == NULL)
-             return false;
-           if (! debug_record_function (info->dhandle, namcopy, return_type,
-                                        false, offset))
-             return false;
          }
       }
       break;
 
     case 10:
-      /* BB10: Assembler module scope.  We completely ignore all this
-        information.  FIXME.  */
+      /* BB10: Assembler module scope.  In the normal case, we
+        completely ignore all this information.  FIXME.  */
       {
        const char *inam, *vstr;
        unsigned long inamlen, vstrlen;
@@ -1139,6 +1188,16 @@ parse_ieee_bb (info, pp)
        boolean present;
        unsigned int i;
 
+       if (! info->saw_filename)
+         {
+           namcopy = savestring (name, namlen);
+           if (namcopy == NULL)
+             return false;
+           if (! debug_set_filename (info->dhandle, namcopy))
+             return false;
+           info->saw_filename = true;
+         }
+
        if (! ieee_read_id (info, pp, &inam, &inamlen)
            || ! ieee_read_number (info, pp, &tool_type)
            || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
@@ -1171,7 +1230,7 @@ parse_ieee_bb (info, pp)
       break;
 
     default:
-      ieee_error (info, block_start, "unknown BB type");
+      ieee_error (info, block_start, _("unknown BB type"));
       return false;
     }
 
@@ -1180,7 +1239,7 @@ parse_ieee_bb (info, pp)
 
   if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
     {
-      ieee_error (info, (const bfd_byte *) NULL, "stack overflow");
+      ieee_error (info, (const bfd_byte *) NULL, _("stack overflow"));
       return false;
     }
 
@@ -1188,6 +1247,7 @@ parse_ieee_bb (info, pp)
   if (b == 5)
     info->blockstack.bsp->filename = namcopy;
   info->blockstack.bsp->fnindx = fnindx;
+  info->blockstack.bsp->skip = skip;
   ++info->blockstack.bsp;
 
   return true;
@@ -1204,19 +1264,53 @@ parse_ieee_be (info, pp)
 
   if (info->blockstack.bsp <= info->blockstack.stack)
     {
-      ieee_error (info, *pp, "stack underflow");
+      ieee_error (info, *pp, _("stack underflow"));
       return false;
     }
   --info->blockstack.bsp;
 
   switch (info->blockstack.bsp->kind)
     {
+    case 2:
+      /* When we end the global typedefs block, we copy out the the
+         contents of info->vars.  This is because the variable indices
+         may be reused in the local blocks.  However, we need to
+         preserve them so that we can locate a function returning a
+         reference variable whose type is named in the global typedef
+         block.  */
+      info->global_vars = ((struct ieee_vars *)
+                          xmalloc (sizeof *info->global_vars));
+      info->global_vars->alloc = info->vars.alloc;
+      info->global_vars->vars = ((struct ieee_var *)
+                                xmalloc (info->vars.alloc
+                                         * sizeof (*info->vars.vars)));
+      memcpy (info->global_vars->vars, info->vars.vars,
+             info->vars.alloc * sizeof (*info->vars.vars));
+
+      /* We also copy out the non builtin parts of info->types, since
+         the types are discarded when we start a new block.  */
+      info->global_types = ((struct ieee_types *)
+                           xmalloc (sizeof *info->global_types));
+      info->global_types->alloc = info->types.alloc;
+      info->global_types->types = ((struct ieee_type *)
+                                  xmalloc (info->types.alloc
+                                           * sizeof (*info->types.types)));
+      memcpy (info->global_types->types, info->types.types,
+             info->types.alloc * sizeof (*info->types.types));
+      memset (info->global_types->builtins, 0,
+             sizeof (info->global_types->builtins));
+
+      break;
+
     case 4:
     case 6:
       if (! ieee_read_expression (info, pp, &offset))
        return false;
-      if (! debug_end_function (info->dhandle, offset))
-       return false;
+      if (! info->blockstack.bsp->skip)
+       {
+         if (! debug_end_function (info->dhandle, offset + 1))
+           return false;
+       }
       break;
 
     case 0x86:
@@ -1224,7 +1318,7 @@ parse_ieee_be (info, pp)
         function.  */
       if (! ieee_read_expression (info, pp, &offset))
        return false;
-      if (! debug_end_block (info->dhandle, offset))
+      if (! debug_end_block (info->dhandle, offset + 1))
        return false;
       break;
 
@@ -1284,7 +1378,7 @@ parse_ieee_nn (info, pp)
 
   if (varindx < 32)
     {
-      ieee_error (info, nn_start, "illegal variable index");
+      ieee_error (info, nn_start, _("illegal variable index"));
       return false;
     }
   varindx -= 32;
@@ -1334,7 +1428,7 @@ parse_ieee_ty (info, pp)
 
   if (typeindx < 256)
     {
-      ieee_error (info, ty_start, "illegal type index");
+      ieee_error (info, ty_start, _("illegal type index"));
       return false;
     }
 
@@ -1344,7 +1438,7 @@ parse_ieee_ty (info, pp)
 
   if (**pp != 0xce)
     {
-      ieee_error (info, *pp, "unknown TY code");
+      ieee_error (info, *pp, _("unknown TY code"));
       return false;
     }
   ++*pp;
@@ -1356,14 +1450,14 @@ parse_ieee_ty (info, pp)
 
   if (varindx < 32)
     {
-      ieee_error (info, ty_var_start, "illegal variable index");
+      ieee_error (info, ty_var_start, _("illegal variable index"));
       return false;
     }
   varindx -= 32;
 
   if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
     {
-      ieee_error (info, ty_var_start, "undefined variable in TY");
+      ieee_error (info, ty_var_start, _("undefined variable in TY"));
       return false;
     }
 
@@ -1381,7 +1475,7 @@ parse_ieee_ty (info, pp)
   switch (tc)
     {
     default:
-      ieee_error (info, ty_code_start, "unknown TY code");
+      ieee_error (info, ty_code_start, _("unknown TY code"));
       return false;
 
     case '!':
@@ -1734,6 +1828,11 @@ parse_ieee_ty (info, pp)
       }
       break;
 
+    case 'V':
+      /* Void.  This is not documented, but the MRI compiler emits it.  */
+      type = debug_make_void_type (dhandle);
+      break;
+
     case 'Z':
       /* Array with 0 lower bound.  */
       {
@@ -1769,22 +1868,37 @@ parse_ieee_ty (info, pp)
 
     case 'f':
       /* Pascal file name.  FIXME.  */
-      ieee_error (info, ty_code_start, "Pascal file name not supported");
+      ieee_error (info, ty_code_start, _("Pascal file name not supported"));
       return false;
 
     case 'g':
       /* Bitfield type.  */
       {
-       bfd_vma signedp, bitsize;
+       bfd_vma signedp, bitsize, dummy;
+       const bfd_byte *hold;
+       boolean present;
 
        if (! ieee_read_number (info, pp, &signedp)
-           || ! ieee_read_number (info, pp, &bitsize)
-           || ! ieee_read_type_index (info, pp, &type))
+           || ! ieee_read_number (info, pp, &bitsize))
          return false;
 
-       /* FIXME: This is just a guess.  */
-       if (! signedp)
-         type = debug_make_int_type (dhandle, 4, true);
+       /* I think the documentation says that there is a type index,
+           but some actual files do not have one.  */
+       hold = *pp;
+       if (! ieee_read_optional_number (info, pp, &dummy, &present))
+         return false;
+       if (! present)
+         {
+           /* FIXME: This is just a guess.  */
+           type = debug_make_int_type (dhandle, 4,
+                                       signedp ? false : true);
+         }
+       else
+         {
+           *pp = hold;
+           if (! ieee_read_type_index (info, pp, &type))
+             return false;
+         }
        type_bitsize = bitsize;
       }
       break;
@@ -1802,7 +1916,7 @@ parse_ieee_ty (info, pp)
        switch (kind)
          {
          default:
-           ieee_error (info, ty_start, "unsupported qualifer");
+           ieee_error (info, ty_start, _("unsupported qualifer"));
            return false;
 
          case 1:
@@ -1935,8 +2049,7 @@ parse_ieee_ty (info, pp)
       break;
     }
 
-  /* Record the type in the table.  If the corresponding NN record has
-     a name, name it.  FIXME: Is this always correct?  */
+  /* Record the type in the table.  */
 
   if (type == DEBUG_TYPE_NULL)
     return false;
@@ -2031,7 +2144,12 @@ parse_ieee_atn (info, pp)
     }
   else if (varindx < 32)
     {
-      ieee_error (info, atn_start, "illegal variable index");
+      /* The MRI compiler reportedly sometimes emits variable lifetime
+         information for a register.  We just ignore it.  */
+      if (atn_code == 9)
+       return ieee_read_number (info, pp, &v);
+
+      ieee_error (info, atn_start, _("illegal variable index"));
       return false;
     }
   else
@@ -2040,8 +2158,38 @@ parse_ieee_atn (info, pp)
       if (varindx >= info->vars.alloc
          || info->vars.vars[varindx].name == NULL)
        {
-         ieee_error (info, atn_start, "undefined variable in ATN");
-         return false;
+         /* The MRI compiler or linker sometimes omits the NN record
+             for a pmisc record.  */
+         if (atn_code == 62)
+           {
+             if (varindx >= info->vars.alloc)
+               {
+                 unsigned int alloc;
+
+                 alloc = info->vars.alloc;
+                 if (alloc == 0)
+                   alloc = 4;
+                 while (varindx >= alloc)
+                   alloc *= 2;
+                 info->vars.vars = ((struct ieee_var *)
+                                    xrealloc (info->vars.vars,
+                                              (alloc
+                                               * sizeof *info->vars.vars)));
+                 memset (info->vars.vars + info->vars.alloc, 0,
+                         ((alloc - info->vars.alloc)
+                          * sizeof *info->vars.vars));
+                 info->vars.alloc = alloc;
+               }
+
+             pvar = info->vars.vars + varindx;
+             pvar->name = "";
+             pvar->namlen = 0;
+           }
+         else
+           {
+             ieee_error (info, atn_start, _("undefined variable in ATN"));
+             return false;
+           }
        }
 
       pvar = info->vars.vars + varindx;
@@ -2082,7 +2230,7 @@ parse_ieee_atn (info, pp)
   switch (atn_code)
     {
     default:
-      ieee_error (info, atn_code_start, "unknown ATN type");
+      ieee_error (info, atn_code_start, _("unknown ATN type"));
       return false;
 
     case 1:
@@ -2185,9 +2333,11 @@ parse_ieee_atn (info, pp)
       return true;
 
     case 10:
-      /* Locked register.  */
+      /* Locked register.  The spec says that there are two required
+         fields, but at least on occasion the MRI compiler only emits
+         one.  */
       if (! ieee_read_number (info, pp, &v)
-         || ! ieee_read_number (info, pp, &v2))
+         || ! ieee_read_optional_number (info, pp, &v2, &present))
        return false;
 
       /* I think this means a variable that is both in a register and
@@ -2202,7 +2352,7 @@ parse_ieee_atn (info, pp)
 
     case 11:
       /* Reserved for FORTRAN common.  */
-      ieee_error (info, atn_code_start, "unsupported ATN11");
+      ieee_error (info, atn_code_start, _("unsupported ATN11"));
 
       /* Return true to keep going.  */
       return true;
@@ -2229,7 +2379,7 @@ parse_ieee_atn (info, pp)
 
       /* We have no way to record this information.  FIXME.  */
 
-      ieee_error (info, atn_code_start, "unsupported ATN12");
+      ieee_error (info, atn_code_start, _("unsupported ATN12"));
 
       /* Return true to keep going.  */
       return true;
@@ -2289,7 +2439,7 @@ parse_ieee_atn (info, pp)
          if (present)
            {
              ieee_error (info, atn_code_start,
-                         "unexpected string in C++ misc");
+                         _("unexpected string in C++ misc"));
              return false;
            }
          return ieee_read_cxx_misc (info, pp, v2);
@@ -2302,7 +2452,7 @@ parse_ieee_atn (info, pp)
          switch ((ieee_record_enum_type) **pp)
            {
            default:
-             ieee_error (info, *pp, "bad misc record");
+             ieee_error (info, *pp, _("bad misc record"));
              return false;
 
            case ieee_at_record_enum:
@@ -2345,7 +2495,7 @@ ieee_read_cxx_misc (info, pp, count)
   switch (category)
     {
     default:
-      ieee_error (info, start, "unrecognized C++ misc record");
+      ieee_error (info, start, _("unrecognized C++ misc record"));
       return false;
 
     case 'T':
@@ -2462,7 +2612,7 @@ ieee_read_cxx_class (info, pp, count)
       break;
   if (it == NULL)
     {
-      ieee_error (info, start, "undefined C++ object");
+      ieee_error (info, start, _("undefined C++ object"));
       return false;
     }
 
@@ -2496,7 +2646,7 @@ ieee_read_cxx_class (info, pp, count)
       switch (id)
        {
        default:
-         ieee_error (info, spec_start, "unrecognized C++ object spec");
+         ieee_error (info, spec_start, _("unrecognized C++ object spec"));
          return false;
 
        case 'b':
@@ -2532,7 +2682,7 @@ ieee_read_cxx_class (info, pp, count)
 
            if ((fieldlen == 0) == (cinline == 0))
              {
-               ieee_error (info, start, "unsupported C++ object type");
+               ieee_error (info, start, _("unsupported C++ object type"));
                return false;
              }
 
@@ -2542,7 +2692,7 @@ ieee_read_cxx_class (info, pp, count)
            free (basecopy);
            if (basetype == DEBUG_TYPE_NULL)
              {
-               ieee_error (info, start, "C++ base class not defined");
+               ieee_error (info, start, _("C++ base class not defined"));
                return false;
              }
 
@@ -2554,7 +2704,7 @@ ieee_read_cxx_class (info, pp, count)
 
                if (structfields == NULL)
                  {
-                   ieee_error (info, start, "C++ object has no fields");
+                   ieee_error (info, start, _("C++ object has no fields"));
                    return false;
                  }
 
@@ -2573,7 +2723,7 @@ ieee_read_cxx_class (info, pp, count)
                if (*pf == DEBUG_FIELD_NULL)
                  {
                    ieee_error (info, start,
-                               "C++ base class not found in container");
+                               _("C++ base class not found in container"));
                    return false;
                  }
 
@@ -2617,7 +2767,7 @@ ieee_read_cxx_class (info, pp, count)
            char *fieldcopy;
            boolean staticp;
            debug_type ftype;
-           const debug_field *pf;
+           const debug_field *pf = NULL;
            enum debug_visibility visibility;
            debug_field field;
 
@@ -2659,7 +2809,7 @@ ieee_read_cxx_class (info, pp, count)
 
                if (structfields == NULL)
                  {
-                   ieee_error (info, start, "C++ object has no fields");
+                   ieee_error (info, start, _("C++ object has no fields"));
                    return false;
                  }
 
@@ -2680,7 +2830,7 @@ ieee_read_cxx_class (info, pp, count)
                if (*pf == DEBUG_FIELD_NULL)
                  {
                    ieee_error (info, start,
-                               "C++ data member not found in container");
+                               _("C++ data member not found in container"));
                    return false;
                  }
 
@@ -2721,7 +2871,7 @@ ieee_read_cxx_class (info, pp, count)
            switch (flags & CXXFLAGS_VISIBILITY)
              {
              default:
-               ieee_error (info, start, "unknown C++ visibility");
+               ieee_error (info, start, _("unknown C++ visibility"));
                return false;
 
              case CXXFLAGS_VISIBILITY_PUBLIC:
@@ -2755,7 +2905,7 @@ ieee_read_cxx_class (info, pp, count)
                bitsize = debug_get_field_bitsize (dhandle, *pf);
                if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
                  {
-                   ieee_error (info, start, "bad C++ field bit pos or size");
+                   ieee_error (info, start, _("bad C++ field bit pos or size"));
                    return false;
                  }
                field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
@@ -2847,7 +2997,7 @@ ieee_read_cxx_class (info, pp, count)
                    != DEBUG_KIND_FUNCTION)
                  {
                    ieee_error (info, start,
-                               "bad type for C++ method function");
+                               _("bad type for C++ method function"));
                    return false;
                  }
 
@@ -2857,7 +3007,7 @@ ieee_read_cxx_class (info, pp, count)
                if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
                  {
                    ieee_error (info, start,
-                               "no type information for C++ method function");
+                               _("no type information for C++ method function"));
                    return false;
                  }
 
@@ -2871,7 +3021,7 @@ ieee_read_cxx_class (info, pp, count)
            switch (flags & CXXFLAGS_VISIBILITY)
              {
              default:
-               ieee_error (info, start, "unknown C++ visibility");
+               ieee_error (info, start, _("unknown C++ visibility"));
                return false;
 
              case CXXFLAGS_VISIBILITY_PUBLIC:
@@ -2896,7 +3046,7 @@ ieee_read_cxx_class (info, pp, count)
              {
                if (id == 'v')
                  {
-                   ieee_error (info, start, "C++ static virtual method");
+                   ieee_error (info, start, _("C++ static virtual method"));
                    return false;
                  }
                mv = debug_make_static_method_variant (dhandle, mangledcopy,
@@ -2991,7 +3141,7 @@ ieee_read_cxx_class (info, pp, count)
            else
              {
                ieee_error (info, start,
-                           "unrecognized C++ object overhead spec");
+                           _("unrecognized C++ object overhead spec"));
                return false;
              }
          }
@@ -3030,7 +3180,7 @@ ieee_read_cxx_class (info, pp, count)
                free (basecopy);
                if (vptrbase == DEBUG_TYPE_NULL)
                  {
-                   ieee_error (info, start, "undefined C++ vtable");
+                   ieee_error (info, start, _("undefined C++ vtable"));
                    return false;
                  }
              }
@@ -3101,7 +3251,7 @@ ieee_read_cxx_defaults (info, pp, count)
   if (info->blockstack.bsp <= info->blockstack.stack
       || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
     {
-      ieee_error (info, start, "C++ default values not in a function");
+      ieee_error (info, start, _("C++ default values not in a function"));
       return false;
     }
 
@@ -3141,7 +3291,7 @@ ieee_read_cxx_defaults (info, pp, count)
          break;
 
        default:
-         ieee_error (info, start, "unrecognized C++ default type");
+         ieee_error (info, start, _("unrecognized C++ default type"));
          return false;
        }
 
@@ -3172,7 +3322,7 @@ ieee_read_cxx_defaults (info, pp, count)
              || (debug_get_type_kind (dhandle, arg_slots[indx])
                  != DEBUG_KIND_POINTER))
            {
-             ieee_error (info, start, "reference parameter is not a pointer");
+             ieee_error (info, start, _("reference parameter is not a pointer"));
              return false;
            }
 
@@ -3219,60 +3369,79 @@ ieee_read_reference (info, pp)
   pslot = NULL;
   if (flags != 3)
     {
-      int i;
-      struct ieee_var *pv = NULL;
+      int pass;
 
       /* We search from the last variable indices to the first in
-        hopes of finding local variables correctly.  FIXME: This
-        probably won't work in all cases.  On the other hand, I don't
-        know what will.  */
-      for (i = (int) info->vars.alloc - 1; i >= 0; i--)
+        hopes of finding local variables correctly.  We search the
+        local variables on the first pass, and the global variables
+        on the second.  FIXME: This probably won't work in all cases.
+        On the other hand, I don't know what will.  */
+      for (pass = 0; pass < 2; pass++)
        {
-         boolean found;
+         struct ieee_vars *vars;
+         int i;
+         struct ieee_var *pv = NULL;
 
-         pv = info->vars.vars + i;
-
-         if (pv->pslot == NULL
-             || pv->namlen != namlen
-             || strncmp (pv->name, name, namlen) != 0)
-           continue;
+         if (pass == 0)
+           vars = &info->vars;
+         else
+           {
+             vars = info->global_vars;
+             if (vars == NULL)
+               break;
+           }
 
-         found = false;
-         switch (flags)
+         for (i = (int) vars->alloc - 1; i >= 0; i--)
            {
-           default:
-             ieee_error (info, start,
-                         "unrecognized C++ reference type");
-             return false;
+             boolean found;
 
-           case 0:
-             /* Global variable or function.  */
-             if (pv->kind == IEEE_GLOBAL
-                 || pv->kind == IEEE_EXTERNAL
-                 || pv->kind == IEEE_FUNCTION)
-               found = true;
-             break;
+             pv = vars->vars + i;
 
-           case 1:
-             /* Global static variable or function.  */
-             if (pv->kind == IEEE_STATIC
-                 || pv->kind == IEEE_FUNCTION)
-               found = true;
-             break;
+             if (pv->pslot == NULL
+                 || pv->namlen != namlen
+                 || strncmp (pv->name, name, namlen) != 0)
+               continue;
 
-           case 2:
-             /* Local variable.  */
-             if (pv->kind == IEEE_LOCAL)
-               found = true;
-             break;
+             found = false;
+             switch (flags)
+               {
+               default:
+                 ieee_error (info, start,
+                             _("unrecognized C++ reference type"));
+                 return false;
+
+               case 0:
+                 /* Global variable or function.  */
+                 if (pv->kind == IEEE_GLOBAL
+                     || pv->kind == IEEE_EXTERNAL
+                     || pv->kind == IEEE_FUNCTION)
+                   found = true;
+                 break;
+
+               case 1:
+                 /* Global static variable or function.  */
+                 if (pv->kind == IEEE_STATIC
+                     || pv->kind == IEEE_FUNCTION)
+                   found = true;
+                 break;
+
+               case 2:
+                 /* Local variable.  */
+                 if (pv->kind == IEEE_LOCAL)
+                   found = true;
+                 break;
+               }
+
+             if (found)
+               break;
            }
 
-         if (found)
-           break;
+         if (i >= 0)
+           {
+             pslot = pv->pslot;
+             break;
+           }
        }
-
-      if (i >= 0)
-       pslot = pv->pslot;
     }
   else
     {
@@ -3320,7 +3489,7 @@ ieee_read_reference (info, pp)
 
   if (pslot == NULL)
     {
-      ieee_error (info, start, "C++ reference not found");
+      ieee_error (info, start, _("C++ reference not found"));
       return false;
     }
 
@@ -3328,7 +3497,7 @@ ieee_read_reference (info, pp)
      to *pslot, which we can now update to be a reference type.  */
   if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
     {
-      ieee_error (info, start, "C++ reference is not pointer");
+      ieee_error (info, start, _("C++ reference is not pointer"));
       return false;
     }
 
@@ -3357,7 +3526,7 @@ ieee_require_asn (info, pp, pv)
   c = (ieee_record_enum_type) **pp;
   if (c != ieee_e2_first_byte_enum)
     {
-      ieee_error (info, start, "missing required ASN");
+      ieee_error (info, start, _("missing required ASN"));
       return false;
     }
   ++*pp;
@@ -3365,7 +3534,7 @@ ieee_require_asn (info, pp, pv)
   c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
   if (c != ieee_asn_record_enum)
     {
-      ieee_error (info, start, "missing required ASN");
+      ieee_error (info, start, _("missing required ASN"));
       return false;
     }
   ++*pp;
@@ -3395,7 +3564,7 @@ ieee_require_atn65 (info, pp, pname, pnamlen)
   c = (ieee_record_enum_type) **pp;
   if (c != ieee_at_record_enum)
     {
-      ieee_error (info, start, "missing required ATN65");
+      ieee_error (info, start, _("missing required ATN65"));
       return false;
     }
   ++*pp;
@@ -3403,7 +3572,7 @@ ieee_require_atn65 (info, pp, pname, pnamlen)
   c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
   if (c != ieee_atn_record_enum)
     {
-      ieee_error (info, start, "missing required ATN65");
+      ieee_error (info, start, _("missing required ATN65"));
       return false;
     }
   ++*pp;
@@ -3417,7 +3586,7 @@ ieee_require_atn65 (info, pp, pname, pnamlen)
 
   if (type_indx != 0 || atn_code != 65)
     {
-      ieee_error (info, start, "bad ATN65 record");
+      ieee_error (info, start, _("bad ATN65 record"));
       return false;
     }
 
@@ -3432,6 +3601,25 @@ ieee_regno_to_genreg (abfd, r)
      bfd *abfd;
      int r;
 {
+  switch (bfd_get_arch (abfd))
+    {
+    case bfd_arch_m68k:
+      /* For some reasons stabs adds 2 to the floating point register
+         numbers.  */
+      if (r >= 16)
+       r += 2;
+      break;
+
+    case bfd_arch_i960:
+      /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+         32 to 35 for fp0 to fp3.  */
+      --r;
+      break;
+
+    default:
+      break;
+    }
+
   return r;
 }
 
@@ -3442,6 +3630,25 @@ ieee_genreg_to_regno (abfd, r)
      bfd *abfd;
      int r;
 {
+  switch (bfd_get_arch (abfd))
+    {
+    case bfd_arch_m68k:
+      /* For some reason stabs add 2 to the floating point register
+         numbers.  */
+      if (r >= 18)
+       r -= 2;
+      break;
+
+    case bfd_arch_i960:
+      /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+         32 to 35 for fp0 to fp3.  */
+      ++r;
+      break;
+
+    default:
+      break;
+    }
+
   return r;
 }
 \f
@@ -3592,6 +3799,8 @@ struct ieee_defined_enum
   struct ieee_defined_enum *next;
   /* Type index.  */
   unsigned int indx;
+  /* Whether this enum has been defined.  */
+  boolean defined;
   /* Tag.  */
   const char *tag;
   /* Names.  */
@@ -3703,6 +3912,10 @@ struct ieee_handle
   struct ieee_modified_type *modified;
   /* Number of entries allocated in modified.  */
   unsigned int modified_alloc;
+  /* 4 byte complex type.  */
+  unsigned int complex_float_index;
+  /* 8 byte complex type.  */
+  unsigned int complex_double_index;
   /* The depth of block nesting.  This is 0 outside a function, and 1
      just after start_function is called.  */
   unsigned int block_depth;
@@ -3892,7 +4105,7 @@ static const struct debug_write_fns ieee_fns =
 /*ARGSUSED*/
 static boolean
 ieee_init_buffer (info, buflist)
-     struct ieee_handle *info;
+     struct ieee_handle *info ATTRIBUTE_UNUSED;
      struct ieee_buflist *buflist;
 {
   buflist->head = NULL;
@@ -3933,7 +4146,7 @@ ieee_change_buffer (info, buflist)
 /*ARGSUSED*/
 static boolean
 ieee_append_buffer (info, mainbuf, newbuf)
-     struct ieee_handle *info;
+     struct ieee_handle *info ATTRIBUTE_UNUSED;
      struct ieee_buflist *mainbuf;
      struct ieee_buflist *newbuf;
 {
@@ -4020,7 +4233,7 @@ ieee_write_number (info, v)
   if (c > (unsigned int) (ieee_number_repeat_end_enum
                          - ieee_number_repeat_start_enum))
     {
-      fprintf (stderr, "IEEE numeric overflow: 0x");
+      fprintf (stderr, _("IEEE numeric overflow: 0x"));
       fprintf_vma (stderr, v);
       fprintf (stderr, "\n");
       return false;
@@ -4066,7 +4279,7 @@ ieee_write_id (info, s)
     }
   else
     {
-      fprintf (stderr, "IEEE string length overflow: %u\n", len);
+      fprintf (stderr, _("IEEE string length overflow: %u\n"), len);
       return false;
     }
 
@@ -4281,7 +4494,7 @@ ieee_start_range (info, low)
   r->next = info->pending_ranges;
   info->pending_ranges = r;
   return true;
-}  
+}
 
 /* Finish a range started by ieee_start_range.  */
 
@@ -4527,7 +4740,18 @@ write_ieee_debugging_info (abfd, dhandle)
   /* Prepend the global typedef information to the other data.  */
   if (! ieee_buffer_emptyp (&info.global_types))
     {
+      /* The HP debugger seems to have a bug in which it ignores the
+         last entry in the global types, so we add a dummy entry.  */
       if (! ieee_change_buffer (&info, &info.global_types)
+         || ! ieee_write_byte (&info, (int) ieee_nn_record)
+         || ! ieee_write_number (&info, info.name_indx)
+         || ! ieee_write_id (&info, "")
+         || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
+         || ! ieee_write_number (&info, info.type_indx)
+         || ! ieee_write_byte (&info, 0xce)
+         || ! ieee_write_number (&info, info.name_indx)
+         || ! ieee_write_number (&info, 'P')
+         || ! ieee_write_number (&info, (int) builtin_void + 32)
          || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
        return false;
 
@@ -4642,6 +4866,14 @@ ieee_write_undefined_tag (h, p)
              return false;
            }
        }
+      else
+       {
+         if (! ieee_change_buffer (info, &info->global_types))
+           {
+             info->error = true;
+             return false;
+           }
+       }
 
       name_indx = info->name_indx;
       ++info->name_indx;
@@ -4695,6 +4927,9 @@ ieee_start_compilation_unit (p, filename)
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
   const char *modname;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  const char *backslash;
+#endif
   char *c, *s;
   unsigned int nindx;
 
@@ -4706,16 +4941,22 @@ ieee_start_compilation_unit (p, filename)
 
   info->filename = filename;
   modname = strrchr (filename, '/');
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  /* We could have a mixed forward/back slash case.  */
+  backslash = strrchr (filename, '\\');
+  if (modname == NULL || (backslash != NULL && backslash > modname))
+    modname = backslash;
+#endif
+
   if (modname != NULL)
     ++modname;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  else if (filename[0] && filename[1] == ':')
+    modname = filename + 2;
+#endif
   else
-    {
-      modname = strrchr (filename, '\\');
-      if (modname != NULL)
-       ++modname;
-      else
-       modname = filename;
-    }
+    modname = filename;
+
   c = xstrdup (modname);
   s = strrchr (c, '.');
   if (s != NULL)
@@ -4861,7 +5102,7 @@ ieee_finish_compilation_unit (info)
 
       /* Coalesce ranges if it seems reasonable.  */
       while (r->next != NULL
-            && high + 64 >= r->next->low
+            && high + 0x1000 >= r->next->low
             && (r->next->high
                 <= (bfd_get_section_vma (info->abfd, s)
                     + bfd_section_size (info->abfd, s))))
@@ -4904,7 +5145,7 @@ ieee_finish_compilation_unit (info)
 
 static void
 ieee_add_bb11_blocks (abfd, sec, data)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
      PTR data;
 {
@@ -4930,7 +5171,8 @@ ieee_add_bb11_blocks (abfd, sec, data)
          return;
        }
 
-      if (low < r->low)
+      if (low < r->low
+         && r->low - low > 0x100)
        {
          if (! ieee_add_bb11 (info, sec, low, r->low))
            {
@@ -4963,21 +5205,29 @@ ieee_add_bb11 (info, sec, low, high)
   else
     {
       const char *filename, *modname;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+      const char *backslash;
+#endif
       char *c, *s;
 
       /* Start the enclosing BB10 block.  */
       filename = bfd_get_filename (info->abfd);
       modname = strrchr (filename, '/');
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+      backslash = strrchr (filename, '\\');
+      if (modname == NULL || (backslash != NULL && backslash > modname))
+       modname = backslash;
+#endif
+
       if (modname != NULL)
        ++modname;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+      else if (filename[0] && filename[1] == ':')
+       modname = filename + 2;
+#endif
       else
-       {
-         modname = strrchr (filename, '\\');
-         if (modname != NULL)
-           ++modname;
-         else
-           modname = filename;
-       }
+       modname = filename;
+
       c = xstrdup (modname);
       s = strrchr (c, '.');
       if (s != NULL)
@@ -5026,8 +5276,8 @@ ieee_add_bb11 (info, sec, low, high)
 /*ARGSUSED*/
 static boolean
 ieee_start_source (p, filename)
-     PTR p;
-     const char *filename;
+     PTR p ATTRIBUTE_UNUSED;
+     const char *filename ATTRIBUTE_UNUSED;
 {
   return true;
 }
@@ -5040,7 +5290,7 @@ ieee_empty_type (p)
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
 
-  return ieee_push_type (info, 0, 0, false, false);
+  return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
 }
 
 /* Make a void type.  */
@@ -5051,7 +5301,7 @@ ieee_void_type (p)
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
 
-  return ieee_push_type (info, 1, 0, false, false);
+  return ieee_push_type (info, (int) builtin_void, 0, false, false);
 }
 
 /* Make an integer type.  */
@@ -5080,7 +5330,7 @@ ieee_int_type (p, size, unsignedp)
       indx = (int) builtin_signed_long_long;
       break;
     default:
-      fprintf (stderr, "IEEE unsupported integer type size %u\n", size);
+      fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size);
       return false;
     }
 
@@ -5116,7 +5366,7 @@ ieee_float_type (p, size)
       indx = (int) builtin_long_long_double;
       break;
     default:
-      fprintf (stderr, "IEEE unsupported float type size %u\n", size);
+      fprintf (stderr, _("IEEE unsupported float type size %u\n"), size);
       return false;
     }
 
@@ -5136,20 +5386,38 @@ ieee_complex_type (p, size)
   switch (size)
     {
     case 4:
+      if (info->complex_float_index != 0)
+       return ieee_push_type (info, info->complex_float_index, size * 2,
+                              false, false);
       code = 'c';
       break;
+    case 12:
+    case 16:
+      /* These cases can be output by gcc -gstabs.  Outputting the
+         wrong type is better than crashing.  */
     case 8:
+      if (info->complex_double_index != 0)
+       return ieee_push_type (info, info->complex_double_index, size * 2,
+                              false, false);
       code = 'd';
       break;
     default:
-      fprintf (stderr, "IEEE unsupported complex type size %u\n", size);
+      fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size);
       return false;
     }
 
   /* FIXME: I don't know what the string is for.  */
-  return (ieee_define_type (info, size, false, false)
-         && ieee_write_number (info, code)
-         && ieee_write_id (info, ""));
+  if (! ieee_define_type (info, size * 2, false, false)
+      || ! ieee_write_number (info, code)
+      || ! ieee_write_id (info, ""))
+    return false;
+
+  if (size == 4)
+    info->complex_float_index = info->type_stack->type.indx;
+  else
+    info->complex_double_index = info->type_stack->type.indx;
+
+  return true;
 }
 
 /* Make a boolean type.  IEEE doesn't support these, so we just make
@@ -5175,9 +5443,11 @@ ieee_enum_type (p, tag, names, vals)
   struct ieee_handle *info = (struct ieee_handle *) p;
   struct ieee_defined_enum *e;
   boolean localp, simple;
-  int i;
+  unsigned int indx;
+  int i = 0;
 
   localp = false;
+  indx = (unsigned int) -1;
   for (e = info->enums; e != NULL; e = e->next)
     {
       if (tag == NULL)
@@ -5193,6 +5463,13 @@ ieee_enum_type (p, tag, names, vals)
            continue;
        }
 
+      if (! e->defined)
+       {
+         /* This enum tag has been seen but not defined.  */
+         indx = e->indx;
+         break;
+       }
+
       if (names != NULL && e->names != NULL)
        {
          for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
@@ -5205,7 +5482,10 @@ ieee_enum_type (p, tag, names, vals)
        }
 
       if ((names == NULL && e->names == NULL)
-         || (names[i] == NULL && e->names[i] == NULL))
+         || (names != NULL
+             && e->names != NULL
+             && names[i] == NULL
+             && e->names[i] == NULL))
        {
          /* We've seen this enum before.  */
          return ieee_push_type (info, e->indx, 0, true, false);
@@ -5237,8 +5517,8 @@ ieee_enum_type (p, tag, names, vals)
        }
     }
 
-  if (! ieee_define_named_type (info, tag, (unsigned int) -1, 0,
-                               true, localp, (struct ieee_buflist *) NULL)
+  if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
+                               (struct ieee_buflist *) NULL)
       || ! ieee_write_number (info, simple ? 'E' : 'N'))
     return false;
   if (simple)
@@ -5264,16 +5544,20 @@ ieee_enum_type (p, tag, names, vals)
 
   if (! localp)
     {
-      e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
-      memset (e, 0, sizeof *e);
+      if (indx == (unsigned int) -1)
+       {
+         e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+         memset (e, 0, sizeof *e);
+         e->indx = info->type_stack->type.indx;
+         e->tag = tag;
+
+         e->next = info->enums;
+         info->enums = e;
+       }
 
-      e->indx = info->type_stack->type.indx;
-      e->tag = tag;
       e->names = names;
       e->vals = vals;
-
-      e->next = info->enums;
-      info->enums = e;
+      e->defined = true;
     }
 
   return true;
@@ -5459,19 +5743,26 @@ ieee_array_type (p, low, high, stringp)
      PTR p;
      bfd_signed_vma low;
      bfd_signed_vma high;
-     boolean stringp;
+     boolean stringp ATTRIBUTE_UNUSED;
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
   unsigned int eleindx;
   boolean localp;
+  unsigned int size;
   struct ieee_modified_type *m = NULL;
   struct ieee_modified_array_type *a;
 
   /* IEEE does not store the range, so we just ignore it.  */
   ieee_pop_unused_type (info);
   localp = info->type_stack->type.localp;
+  size = info->type_stack->type.size;
   eleindx = ieee_pop_type (info);
 
+  /* If we don't know the range, treat the size as exactly one
+     element.  */
+  if (low < high)
+    size *= (high - low) + 1;
+
   if (! localp)
     {
       m = ieee_get_modified_info (info, eleindx);
@@ -5481,11 +5772,11 @@ ieee_array_type (p, low, high, stringp)
       for (a = m->arrays; a != NULL; a = a->next)
        {
          if (a->low == low && a->high == high)
-           return ieee_push_type (info, a->indx, 0, false, false);
+           return ieee_push_type (info, a->indx, size, false, false);
        }
     }
 
-  if (! ieee_define_type (info, 0, false, localp)
+  if (! ieee_define_type (info, size, false, localp)
       || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
       || ! ieee_write_number (info, eleindx))
     return false;
@@ -5519,7 +5810,7 @@ ieee_array_type (p, low, high, stringp)
 static boolean
 ieee_set_type (p, bitstringp)
      PTR p;
-     boolean bitstringp;
+     boolean bitstringp ATTRIBUTE_UNUSED;
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
   boolean localp;
@@ -5556,7 +5847,7 @@ ieee_offset_type (p)
      which seems pretty important.  I'm going to punt this for now.  */
 
   return ieee_int_type (p, 4, true);
-}  
+}
 
 /* Make a method type.  */
 
@@ -6417,6 +6708,30 @@ ieee_tag_type (p, name, id, kind)
   struct ieee_name_type_hash_entry *h;
   struct ieee_name_type *nt;
 
+  if (kind == DEBUG_KIND_ENUM)
+    {
+      struct ieee_defined_enum *e;
+
+      if (name == NULL)
+       abort ();
+      for (e = info->enums; e != NULL; e = e->next)
+       if (e->tag != NULL && strcmp (e->tag, name) == 0)
+         return ieee_push_type (info, e->indx, 0, true, false);
+
+      e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+      memset (e, 0, sizeof *e);
+
+      e->indx = info->type_indx;
+      ++info->type_indx;
+      e->tag = name;
+      e->defined = false;
+
+      e->next = info->enums;
+      info->enums = e;
+
+      return ieee_push_type (info, e->indx, 0, true, false);
+    }
+
   localp = false;
 
   copy = false;
@@ -6715,7 +7030,7 @@ ieee_typdef (p, name)
 static boolean
 ieee_tag (p, name)
      PTR p;
-     const char *name;
+     const char *name ATTRIBUTE_UNUSED;
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
 
@@ -6729,9 +7044,9 @@ ieee_tag (p, name)
 
 static boolean
 ieee_int_constant (p, name, val)
-     PTR p;
-     const char *name;
-     bfd_vma val;
+     PTR p ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
+     bfd_vma val ATTRIBUTE_UNUSED;
 {
   /* FIXME.  */
   return true;
@@ -6741,9 +7056,9 @@ ieee_int_constant (p, name, val)
 
 static boolean
 ieee_float_constant (p, name, val)
-     PTR p;
-     const char *name;
-     double val;
+     PTR p ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
+     double val ATTRIBUTE_UNUSED;
 {
   /* FIXME.  */
   return true;
@@ -6754,8 +7069,8 @@ ieee_float_constant (p, name, val)
 static boolean
 ieee_typed_constant (p, name, val)
      PTR p;
-     const char *name;
-     bfd_vma val;
+     const char *name ATTRIBUTE_UNUSED;
+     bfd_vma val ATTRIBUTE_UNUSED;
 {
   struct ieee_handle *info = (struct ieee_handle *) p;
 
@@ -7006,7 +7321,7 @@ ieee_function_parameter (p, name, kind, val)
     return false;
   ++info->fnargcount;
 
-  return true;  
+  return true;
 }
 
 /* Output pending function parameters.  */
@@ -7265,7 +7580,7 @@ ieee_lineno (p, filename, lineno, addr)
                return false;
              if (strcmp (info->filename, info->pending_lineno_filename) == 0)
                {
-                 /* We need a new NN record, and we aren't output to
+                 /* We need a new NN record, and we aren't about to
                     output one.  */
                  info->lineno_name_indx = info->name_indx;
                  ++info->name_indx;
This page took 0.044626 seconds and 4 git commands to generate.