*** empty log message ***
[binutils-gdb.git] / binutils / debug.c
index c47f1b04b2b244065bf7f5502666be26c361b3ed..3d7d48e2bbf98d183492d8d70411945917ff7558 100644 (file)
@@ -1,5 +1,5 @@
 /* debug.c -- Handle generic debugging information.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
@@ -56,6 +56,9 @@ struct debug_handle
   unsigned int class_id;
   /* The base for class_id for this call to debug_write.  */
   unsigned int base_id;
+  /* The current line number in debug_write.  */
+  struct debug_lineno *current_write_lineno;
+  unsigned int current_write_lineno_index;
   /* A list of classes which have assigned ID's during debug_write.
      This is linked through the next_id field of debug_class_type.  */
   struct debug_class_id *id_list;
@@ -108,7 +111,7 @@ struct debug_type
       struct debug_indirect_type *kindirect;
       /* DEBUG_KIND_INT.  */
       /* Whether the integer is unsigned.  */
-      boolean kint;
+      bfd_boolean kint;
       /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
          DEBUG_KIND_UNION_CLASS.  */
       struct debug_class_type *kclass;
@@ -191,7 +194,7 @@ struct debug_function_type
   /* NULL terminated array of argument types.  */
   debug_type *arg_types;
   /* Whether the function takes a variable number of arguments.  */
-  boolean varargs;
+  bfd_boolean varargs;
 };
 
 /* Information kept for a range.  */
@@ -219,7 +222,7 @@ struct debug_array_type
   /* Upper bound.  */
   bfd_signed_vma upper;
   /* Whether this array is really a string.  */
-  boolean stringp;
+  bfd_boolean stringp;
 };
 
 /* Information kept for a set.  */
@@ -229,7 +232,7 @@ struct debug_set_type
   /* Base type.  */
   debug_type type;
   /* Whether this set is really a bitstring.  */
-  boolean bitstringp;
+  bfd_boolean bitstringp;
 };
 
 /* Information kept for an offset type (a based pointer).  */
@@ -253,7 +256,7 @@ struct debug_method_type
   /* A NULL terminated array of argument types.  */
   debug_type *arg_types;
   /* Whether the method takes a variable number of arguments.  */
-  boolean varargs;
+  bfd_boolean varargs;
 };
 
 /* Information kept for a named type.  */
@@ -277,7 +280,7 @@ struct debug_field
   /* Visibility of the field.  */
   enum debug_visibility visibility;
   /* Whether this is a static member.  */
-  boolean static_member;
+  bfd_boolean static_member;
   union
     {
       /* If static_member is false.  */
@@ -305,7 +308,7 @@ struct debug_baseclass
   /* Bit position of the base class in the object.  */
   unsigned int bitpos;
   /* Whether the base class is virtual.  */
-  boolean virtual;
+  bfd_boolean virtual;
   /* Visibility of the base class.  */
   enum debug_visibility visibility;
 };
@@ -332,9 +335,9 @@ struct debug_method_variant
   /* The visibility of the function.  */
   enum debug_visibility visibility;
   /* Whether the function is const.  */
-  boolean constp;
+  bfd_boolean constp;
   /* Whether the function is volatile.  */
-  boolean volatilep;
+  bfd_boolean volatilep;
   /* The offset to the function in the virtual function table.  */
   bfd_vma voffset;
   /* If voffset is VOFFSET_STATIC_METHOD, this is a static method.  */
@@ -538,9 +541,21 @@ struct debug_type_compare_list
   struct debug_type *t2;
 };
 
+/* During debug_get_real_type, a linked list of these structures is
+   kept on the stack to avoid infinite recursion.  */
+
+struct debug_type_real_list
+{
+  /* Next type on list.  */
+  struct debug_type_real_list *next;
+  /* The type we are checking.  */
+  struct debug_type *t;
+};
+
 /* Local functions.  */
 
-static void debug_error PARAMS ((const char *));
+static void debug_error
+  PARAMS ((const char *));
 static struct debug_name *debug_add_to_namespace
   PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
           enum debug_object_kind, enum debug_object_linkage));
@@ -549,27 +564,31 @@ static struct debug_name *debug_add_to_current_namespace
           enum debug_object_linkage));
 static struct debug_type *debug_make_type
   PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
-static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type));
-static boolean debug_write_name
+static struct debug_type *debug_get_real_type
+  PARAMS ((PTR, debug_type, struct debug_type_real_list *));
+static bfd_boolean debug_write_name
   PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
           struct debug_name *));
-static boolean debug_write_type
+static bfd_boolean debug_write_type
   PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
           struct debug_type *, struct debug_name *));
-static boolean debug_write_class_type
+static bfd_boolean debug_write_class_type
   PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
           struct debug_type *, const char *));
-static boolean debug_write_function
+static bfd_boolean debug_write_function
   PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
           const char *, enum debug_object_linkage, struct debug_function *));
-static boolean debug_write_block
+static bfd_boolean debug_write_block
   PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
           struct debug_block *));
-static boolean debug_set_class_id
+static bfd_boolean debug_write_linenos
+  PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+          bfd_vma));
+static bfd_boolean debug_set_class_id
   PARAMS ((struct debug_handle *, const char *, struct debug_type *));
-static boolean debug_type_samep
+static bfd_boolean debug_type_samep
   PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
-static boolean debug_class_type_samep
+static bfd_boolean debug_class_type_samep
   PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
 \f
 /* Issue an error message.  */
@@ -585,7 +604,7 @@ debug_error (message)
 
 static struct debug_name *
 debug_add_to_namespace (info, nsp, name, kind, linkage)
-     struct debug_handle *info;
+     struct debug_handle *info ATTRIBUTE_UNUSED;
      struct debug_namespace **nsp;
      const char *name;
      enum debug_object_kind kind;
@@ -632,7 +651,7 @@ debug_add_to_current_namespace (info, name, kind, linkage)
   if (info->current_unit == NULL
       || info->current_file == NULL)
     {
-      debug_error ("debug_add_to_current_namespace: no current file");
+      debug_error (_("debug_add_to_current_namespace: no current file"));
       return NULL;
     }
 
@@ -659,7 +678,7 @@ debug_init ()
 /* Set the source filename.  This implicitly starts a new compilation
    unit.  */
 
-boolean
+bfd_boolean
 debug_set_filename (handle, name)
      PTR handle;
      const char *name;
@@ -696,13 +715,13 @@ debug_set_filename (handle, name)
   info->current_block = NULL;
   info->current_lineno = NULL;
 
-  return true;
+  return TRUE;
 }
 
 /* Change source files to the given file name.  This is used for
    include files in a single compilation unit.  */
 
-boolean
+bfd_boolean
 debug_start_source (handle, name)
      PTR handle;
      const char *name;
@@ -715,8 +734,8 @@ debug_start_source (handle, name)
 
   if (info->current_unit == NULL)
     {
-      debug_error ("debug_start_source: no debug_set_filename call");
-      return false;
+      debug_error (_("debug_start_source: no debug_set_filename call"));
+      return FALSE;
     }
 
   for (f = info->current_unit->files; f != NULL; f = f->next)
@@ -726,7 +745,7 @@ debug_start_source (handle, name)
          && strcmp (f->filename, name) == 0)
        {
          info->current_file = f;
-         return true;
+         return TRUE;
        }
     }
 
@@ -743,7 +762,7 @@ debug_start_source (handle, name)
 
   info->current_file = f;
 
-  return true;
+  return TRUE;
 }
 
 /* Record a function definition.  This implicitly starts a function
@@ -754,12 +773,12 @@ debug_start_source (handle, name)
    debug_record_parameter.  FIXME: There is no way to specify nested
    functions.  */
 
-boolean
+bfd_boolean
 debug_record_function (handle, name, return_type, global, addr)
      PTR handle;
      const char *name;
      debug_type return_type;
-     boolean global;
+     bfd_boolean global;
      bfd_vma addr;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
@@ -770,12 +789,12 @@ debug_record_function (handle, name, return_type, global, addr)
   if (name == NULL)
     name = "";
   if (return_type == NULL)
-    return false;
+    return FALSE;
 
   if (info->current_unit == NULL)
     {
-      debug_error ("debug_record_function: no debug_set_filename call");
-      return false;
+      debug_error (_("debug_record_function: no debug_set_filename call"));
+      return FALSE;
     }
 
   f = (struct debug_function *) xmalloc (sizeof *f);
@@ -804,16 +823,16 @@ debug_record_function (handle, name, return_type, global, addr)
                               ? DEBUG_LINKAGE_GLOBAL
                               : DEBUG_LINKAGE_STATIC));
   if (n == NULL)
-    return false;
+    return FALSE;
 
   n->u.function = f;
 
-  return true;
+  return TRUE;
 }
 
 /* Record a parameter for the current function.  */
 
-boolean
+bfd_boolean
 debug_record_parameter (handle, name, type, kind, val)
      PTR handle;
      const char *name;
@@ -825,13 +844,13 @@ debug_record_parameter (handle, name, type, kind, val)
   struct debug_parameter *p, **pp;
 
   if (name == NULL || type == NULL)
-    return false;
+    return FALSE;
 
   if (info->current_unit == NULL
       || info->current_function == NULL)
     {
-      debug_error ("debug_record_parameter: no current function");
-      return false;
+      debug_error (_("debug_record_parameter: no current function"));
+      return FALSE;
     }
 
   p = (struct debug_parameter *) xmalloc (sizeof *p);
@@ -848,12 +867,12 @@ debug_record_parameter (handle, name, type, kind, val)
     ;
   *pp = p;
 
-  return true;
+  return TRUE;
 }
 
 /* End a function.  FIXME: This should handle function nesting.  */
 
-boolean
+bfd_boolean
 debug_end_function (handle, addr)
      PTR handle;
      bfd_vma addr;
@@ -864,14 +883,14 @@ debug_end_function (handle, addr)
       || info->current_block == NULL
       || info->current_function == NULL)
     {
-      debug_error ("debug_end_function: no current function");
-      return false;
+      debug_error (_("debug_end_function: no current function"));
+      return FALSE;
     }
 
   if (info->current_block->parent != NULL)
     {
-      debug_error ("debug_end_function: some blocks were not closed");
-      return false;
+      debug_error (_("debug_end_function: some blocks were not closed"));
+      return FALSE;
     }
 
   info->current_block->end = addr;
@@ -879,7 +898,7 @@ debug_end_function (handle, addr)
   info->current_function = NULL;
   info->current_block = NULL;
 
-  return true;
+  return TRUE;
 }
 
 /* Start a block in a function.  All local information will be
@@ -887,7 +906,7 @@ debug_end_function (handle, addr)
    debug_start_block and debug_end_block may be nested.  The bfd_vma
    argument is the address at which this block starts.  */
 
-boolean
+bfd_boolean
 debug_start_block (handle, addr)
      PTR handle;
      bfd_vma addr;
@@ -900,8 +919,8 @@ debug_start_block (handle, addr)
   if (info->current_unit == NULL
       || info->current_block == NULL)
     {
-      debug_error ("debug_start_block: no current block");
-      return false;
+      debug_error (_("debug_start_block: no current block"));
+      return FALSE;
     }
 
   b = (struct debug_block *) xmalloc (sizeof *b);
@@ -920,14 +939,14 @@ debug_start_block (handle, addr)
 
   info->current_block = b;
 
-  return true;
+  return TRUE;
 }
 
 /* Finish a block in a function.  This matches the call to
    debug_start_block.  The argument is the address at which this block
    ends.  */
 
-boolean
+bfd_boolean
 debug_end_block (handle, addr)
      PTR handle;
      bfd_vma addr;
@@ -938,28 +957,28 @@ debug_end_block (handle, addr)
   if (info->current_unit == NULL
       || info->current_block == NULL)
     {
-      debug_error ("debug_end_block: no current block");
-      return false;
+      debug_error (_("debug_end_block: no current block"));
+      return FALSE;
     }
 
   parent = info->current_block->parent;
   if (parent == NULL)
     {
-      debug_error ("debug_end_block: attempt to close top level block");
-      return false;
+      debug_error (_("debug_end_block: attempt to close top level block"));
+      return FALSE;
     }
 
   info->current_block->end = addr;
 
   info->current_block = parent;
 
-  return true;
+  return TRUE;
 }
 
 /* Associate a line number in the current source file and function
    with a given address.  */
 
-boolean
+bfd_boolean
 debug_record_line (handle, lineno, addr)
      PTR handle;
      unsigned long lineno;
@@ -971,8 +990,8 @@ debug_record_line (handle, lineno, addr)
 
   if (info->current_unit == NULL)
     {
-      debug_error ("debug_record_line: no current unit");
-      return false;
+      debug_error (_("debug_record_line: no current unit"));
+      return FALSE;
     }
 
   l = info->current_lineno;
@@ -984,7 +1003,7 @@ debug_record_line (handle, lineno, addr)
            {
              l->linenos[i] = lineno;
              l->addrs[i] = addr;
-             return true;
+             return TRUE;
            }
        }
     }
@@ -1013,37 +1032,37 @@ debug_record_line (handle, lineno, addr)
 
   info->current_lineno = l;
 
-  return true;
+  return TRUE;
 }
 
 /* Start a named common block.  This is a block of variables that may
    move in memory.  */
 
-boolean
+bfd_boolean
 debug_start_common_block (handle, name)
-     PTR handle;
-     const char *name;
+     PTR handle ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
 {
   /* FIXME */
-  debug_error ("debug_start_common_block: not implemented");
-  return false;
+  debug_error (_("debug_start_common_block: not implemented"));
+  return FALSE;
 }
 
 /* End a named common block.  */
 
-boolean
+bfd_boolean
 debug_end_common_block (handle, name)
-     PTR handle;
-     const char *name;
+     PTR handle ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
 {
   /* FIXME */
-  debug_error ("debug_end_common_block: not implemented");
-  return false;
+  debug_error (_("debug_end_common_block: not implemented"));
+  return FALSE;
 }
 
 /* Record a named integer constant.  */
 
-boolean
+bfd_boolean
 debug_record_int_const (handle, name, val)
      PTR handle;
      const char *name;
@@ -1053,21 +1072,21 @@ debug_record_int_const (handle, name, val)
   struct debug_name *n;
 
   if (name == NULL)
-    return false;
+    return FALSE;
 
   n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
                                      DEBUG_LINKAGE_NONE);
   if (n == NULL)
-    return false;
+    return FALSE;
 
   n->u.int_constant = val;
 
-  return true;
+  return TRUE;
 }
 
 /* Record a named floating point constant.  */
 
-boolean
+bfd_boolean
 debug_record_float_const (handle, name, val)
      PTR handle;
      const char *name;
@@ -1077,21 +1096,21 @@ debug_record_float_const (handle, name, val)
   struct debug_name *n;
 
   if (name == NULL)
-    return false;
+    return FALSE;
 
   n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
                                      DEBUG_LINKAGE_NONE);
   if (n == NULL)
-    return false;
+    return FALSE;
 
   n->u.float_constant = val;
 
-  return true;
+  return TRUE;
 }
 
 /* Record a typed constant with an integral value.  */
 
-boolean
+bfd_boolean
 debug_record_typed_const (handle, name, type, val)
      PTR handle;
      const char *name;
@@ -1103,12 +1122,12 @@ debug_record_typed_const (handle, name, type, val)
   struct debug_typed_constant *tc;
 
   if (name == NULL || type == NULL)
-    return false;
+    return FALSE;
 
   n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
                                      DEBUG_LINKAGE_NONE);
   if (n == NULL)
-    return false;
+    return FALSE;
 
   tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
   memset (tc, 0, sizeof *tc);
@@ -1118,26 +1137,26 @@ debug_record_typed_const (handle, name, type, val)
 
   n->u.typed_constant = tc;
 
-  return true;
+  return TRUE;
 }
 
 /* Record a label.  */
 
-boolean
+bfd_boolean
 debug_record_label (handle, name, type, addr)
-     PTR handle;
-     const char *name;
-     debug_type type;
-     bfd_vma addr;
+     PTR handle ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
+     debug_type type ATTRIBUTE_UNUSED;
+     bfd_vma addr ATTRIBUTE_UNUSED;
 {
   /* FIXME.  */
-  debug_error ("debug_record_label not implemented");
-  return false;
+  debug_error (_("debug_record_label: not implemented"));
+  return FALSE;
 }
 
 /* Record a variable.  */
 
-boolean
+bfd_boolean
 debug_record_variable (handle, name, type, kind, val)
      PTR handle;
      const char *name;
@@ -1152,13 +1171,13 @@ debug_record_variable (handle, name, type, kind, val)
   struct debug_variable *v;
 
   if (name == NULL || type == NULL)
-    return false;
+    return FALSE;
 
   if (info->current_unit == NULL
       || info->current_file == NULL)
     {
-      debug_error ("debug_record_variable: no current file");
-      return false;
+      debug_error (_("debug_record_variable: no current file"));
+      return FALSE;
     }
 
   if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
@@ -1172,17 +1191,15 @@ debug_record_variable (handle, name, type, kind, val)
   else
     {
       if (info->current_block == NULL)
-       {
-         debug_error ("debug_record_variable: no current block");
-         return false;
-       }
-      nsp = &info->current_block->locals;
+       nsp = &info->current_file->globals;
+      else
+       nsp = &info->current_block->locals;
       linkage = DEBUG_LINKAGE_AUTOMATIC;
     }
 
   n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
   if (n == NULL)
-    return false;
+    return FALSE;
 
   v = (struct debug_variable *) xmalloc (sizeof *v);
   memset (v, 0, sizeof *v);
@@ -1193,15 +1210,14 @@ debug_record_variable (handle, name, type, kind, val)
 
   n->u.variable = v;
 
-  return true;  
+  return TRUE;
 }
 
 /* Make a type with a given kind and size.  */
 
-/*ARGSUSED*/
 static struct debug_type *
 debug_make_type (info, kind, size)
-     struct debug_handle *info;
+     struct debug_handle *info ATTRIBUTE_UNUSED;
      enum debug_type_kind kind;
      unsigned int size;
 {
@@ -1262,7 +1278,7 @@ debug_type
 debug_make_int_type (handle, size, unsignedp)
      PTR handle;
      unsigned int size;
-     boolean unsignedp;
+     bfd_boolean unsignedp;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1321,7 +1337,7 @@ debug_make_complex_type (handle, size)
 debug_type
 debug_make_struct_type (handle, structp, size, fields)
      PTR handle;
-     boolean structp;
+     bfd_boolean structp;
      bfd_vma size;
      debug_field *fields;
 {
@@ -1356,13 +1372,13 @@ debug_type
 debug_make_object_type (handle, structp, size, fields, baseclasses,
                        methods, vptrbase, ownvptr)
      PTR handle;
-     boolean structp;
+     bfd_boolean structp;
      bfd_vma size;
      debug_field *fields;
      debug_baseclass *baseclasses;
      debug_method *methods;
      debug_type vptrbase;
-     boolean ownvptr;
+     bfd_boolean ownvptr;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1453,7 +1469,7 @@ debug_make_function_type (handle, type, arg_types, varargs)
      PTR handle;
      debug_type type;
      debug_type *arg_types;
-     boolean varargs;
+     bfd_boolean varargs;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1546,7 +1562,7 @@ debug_make_array_type (handle, element_type, range_type, lower, upper,
      debug_type range_type;
      bfd_signed_vma lower;
      bfd_signed_vma upper;
-     boolean stringp;
+     bfd_boolean stringp;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1581,7 +1597,7 @@ debug_type
 debug_make_set_type (handle, type, bitstringp)
      PTR handle;
      debug_type type;
-     boolean bitstringp;
+     bfd_boolean bitstringp;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1648,7 +1664,7 @@ debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
      debug_type return_type;
      debug_type domain_type;
      debug_type *arg_types;
-     boolean varargs;
+     bfd_boolean varargs;
 {
   struct debug_handle *info = (struct debug_handle *) handle;
   struct debug_type *t;
@@ -1743,7 +1759,7 @@ debug_make_undefined_tagged_type (handle, name, kind)
       break;
 
     default:
-      debug_error ("debug_make_undefined_type: unsupported kind");
+      debug_error (_("debug_make_undefined_type: unsupported kind"));
       return DEBUG_TYPE_NULL;
     }
 
@@ -1760,15 +1776,14 @@ debug_make_undefined_tagged_type (handle, name, kind)
    The fourth argument is whether this is a virtual class.  The fifth
    argument is the visibility of the base class.  */
 
-/*ARGSUSED*/
 debug_baseclass
 debug_make_baseclass (handle, type, bitpos, virtual, visibility)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_type type;
      bfd_vma bitpos;
-     boolean virtual;
+     bfd_boolean virtual;
      enum debug_visibility visibility;
-{     
+{
   struct debug_baseclass *b;
 
   b = (struct debug_baseclass *) xmalloc (sizeof *b);
@@ -1788,10 +1803,9 @@ debug_make_baseclass (handle, type, bitpos, virtual, visibility)
    the field (it may be zero).  The sixth argument is the visibility
    of the field.  */
 
-/*ARGSUSED*/
 debug_field
 debug_make_field (handle, name, type, bitpos, bitsize, visibility)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      const char *name;
      debug_type type;
      bfd_vma bitpos;
@@ -1805,7 +1819,7 @@ debug_make_field (handle, name, type, bitpos, bitsize, visibility)
 
   f->name = name;
   f->type = type;
-  f->static_member = false;
+  f->static_member = FALSE;
   f->u.f.bitpos = bitpos;
   f->u.f.bitsize = bitsize;
   f->visibility = visibility;
@@ -1819,10 +1833,9 @@ debug_make_field (handle, name, type, bitpos, bitsize, visibility)
    global variable).  The fifth argument is the visibility of the
    member.  */
 
-/*ARGSUSED*/
 debug_field
 debug_make_static_member (handle, name, type, physname, visibility)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      const char *name;
      debug_type type;
      const char *physname;
@@ -1835,7 +1848,7 @@ debug_make_static_member (handle, name, type, physname, visibility)
 
   f->name = name;
   f->type = type;
-  f->static_member = true;
+  f->static_member = TRUE;
   f->u.s.physname = physname;
   f->visibility = visibility;
 
@@ -1845,10 +1858,9 @@ debug_make_static_member (handle, name, type, physname, visibility)
 /* Make a method.  The second argument is the name, and the third
    argument is a NULL terminated array of method variants.  */
 
-/*ARGSUSED*/
 debug_method
 debug_make_method (handle, name, variants)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      const char *name;
      debug_method_variant *variants;
 {
@@ -1872,16 +1884,15 @@ debug_make_method (handle, name, variants)
    function context.  FIXME: Are the const and volatile arguments
    necessary?  Could we just use debug_make_const_type?  */
 
-/*ARGSUSED*/
 debug_method_variant
 debug_make_method_variant (handle, physname, type, visibility, constp,
                           volatilep, voffset, context)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      const char *physname;
      debug_type type;
      enum debug_visibility visibility;
-     boolean constp;
-     boolean volatilep;
+     bfd_boolean constp;
+     bfd_boolean volatilep;
      bfd_vma voffset;
      debug_type context;
 {
@@ -1908,12 +1919,12 @@ debug_make_method_variant (handle, physname, type, visibility, constp,
 debug_method_variant
 debug_make_static_method_variant (handle, physname, type, visibility,
                                  constp, volatilep)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      const char *physname;
      debug_type type;
      enum debug_visibility visibility;
-     boolean constp;
-     boolean volatilep;
+     bfd_boolean constp;
+     bfd_boolean volatilep;
 {
   struct debug_method_variant *m;
 
@@ -1949,8 +1960,8 @@ debug_name_type (handle, name, type)
   if (info->current_unit == NULL
       || info->current_file == NULL)
     {
-      debug_error ("debug_record_variable: no current file");
-      return false;
+      debug_error (_("debug_name_type: no current file"));
+      return DEBUG_TYPE_NULL;
     }
 
   t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
@@ -1970,7 +1981,7 @@ debug_name_type (handle, name, type)
   nm = debug_add_to_namespace (info, &info->current_file->globals, name,
                               DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
   if (nm == NULL)
-    return false;
+    return DEBUG_TYPE_NULL;
 
   nm->u.type = t;
 
@@ -1997,7 +2008,7 @@ debug_tag_type (handle, name, type)
 
   if (info->current_file == NULL)
     {
-      debug_error ("debug_tag_type: no current file");
+      debug_error (_("debug_tag_type: no current file"));
       return DEBUG_TYPE_NULL;
     }
 
@@ -2005,7 +2016,7 @@ debug_tag_type (handle, name, type)
     {
       if (strcmp (type->u.knamed->name->name, name) == 0)
        return type;
-      debug_error ("debug_tag_type: extra tag attempted");
+      debug_error (_("debug_tag_type: extra tag attempted"));
       return DEBUG_TYPE_NULL;
     }
 
@@ -2026,7 +2037,7 @@ debug_tag_type (handle, name, type)
   nm = debug_add_to_namespace (info, &info->current_file->globals, name,
                               DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
   if (nm == NULL)
-    return false;
+    return DEBUG_TYPE_NULL;
 
   nm->u.tag = t;
 
@@ -2037,20 +2048,19 @@ debug_tag_type (handle, name, type)
 
 /* Record the size of a given type.  */
 
-/*ARGSUSED*/
-boolean
+bfd_boolean
 debug_record_type_size (handle, type, size)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_type type;
      unsigned int size;
 {
   if (type->size != 0 && type->size != size)
-    fprintf (stderr, "Warning: changing type size from %d to %d\n",
+    fprintf (stderr, _("Warning: changing type size from %d to %d\n"),
             type->size, size);
 
   type->size = size;
 
-  return true;
+  return TRUE;
 }
 
 /* Find a named type.  */
@@ -2069,7 +2079,7 @@ debug_find_named_type (handle, name)
 
   if (info->current_unit == NULL)
     {
-      debug_error ("debug_find_named_type: no current compilation unit");
+      debug_error (_("debug_find_named_type: no current compilation unit"));
       return DEBUG_TYPE_NULL;
     }
 
@@ -2105,7 +2115,7 @@ debug_find_named_type (handle, name)
        }
     }
 
-  return DEBUG_TYPE_NULL;        
+  return DEBUG_TYPE_NULL;
 }
 
 /* Find a tagged type.  */
@@ -2148,24 +2158,54 @@ debug_find_tagged_type (handle, name, kind)
   return DEBUG_TYPE_NULL;
 }
 
-/* Get a base type.  */
+/* Get a base type.  We build a linked list on the stack to avoid
+   crashing if the type is defined circularly.  */
 
 static struct debug_type *
-debug_get_real_type (handle, type)
+debug_get_real_type (handle, type, list)
      PTR handle;
      debug_type type;
+     struct debug_type_real_list *list;
 {
+  struct debug_type_real_list *l;
+  struct debug_type_real_list rl;
+
   switch (type->kind)
     {
     default:
       return type;
+
+    case DEBUG_KIND_INDIRECT:
+    case DEBUG_KIND_NAMED:
+    case DEBUG_KIND_TAGGED:
+      break;
+    }
+
+  for (l = list; l != NULL; l = l->next)
+    {
+      if (l->t == type || l == l->next)
+       {
+         fprintf (stderr,
+                  _("debug_get_real_type: circular debug information for %s\n"),
+                  debug_get_type_name (handle, type));
+         return NULL;
+       }
+    }
+
+  rl.next = list;
+  rl.t = type;
+
+  switch (type->kind)
+    {
+      /* The default case is just here to avoid warnings.  */
+    default:
     case DEBUG_KIND_INDIRECT:
       if (*type->u.kindirect->slot != NULL)
-       return debug_get_real_type (handle, *type->u.kindirect->slot);
+       return debug_get_real_type (handle, *type->u.kindirect->slot, &rl);
       return type;
     case DEBUG_KIND_NAMED:
     case DEBUG_KIND_TAGGED:
-      return debug_get_real_type (handle, type->u.knamed->type);
+      return debug_get_real_type (handle, type->u.knamed->type, &rl);
     }
   /*NOTREACHED*/
 }
@@ -2179,7 +2219,9 @@ debug_get_type_kind (handle, type)
 {
   if (type == NULL)
     return DEBUG_KIND_ILLEGAL;
-  type = debug_get_real_type (handle, type);
+  type = debug_get_real_type (handle, type, NULL);
+  if (type == NULL)
+    return DEBUG_KIND_ILLEGAL;
   return type->kind;
 }
 
@@ -2242,7 +2284,11 @@ debug_get_return_type (handle, type)
 {
   if (type == NULL)
     return DEBUG_TYPE_NULL;
-  type = debug_get_real_type (handle, type);
+
+  type = debug_get_real_type (handle, type, NULL);
+  if (type == NULL)
+    return DEBUG_TYPE_NULL;
+
   switch (type->kind)
     {
     default:
@@ -2252,7 +2298,7 @@ debug_get_return_type (handle, type)
     case DEBUG_KIND_METHOD:
       return type->u.kmethod->return_type;
     }
-  /*NOTREACHED*/      
+  /*NOTREACHED*/
 }
 
 /* Get the parameter types of a function or method type (except that
@@ -2262,11 +2308,15 @@ const debug_type *
 debug_get_parameter_types (handle, type, pvarargs)
      PTR handle;
      debug_type type;
-     boolean *pvarargs;
+     bfd_boolean *pvarargs;
 {
   if (type == NULL)
     return NULL;
-  type = debug_get_real_type (handle, type);
+
+  type = debug_get_real_type (handle, type, NULL);
+  if (type == NULL)
+    return NULL;
+
   switch (type->kind)
     {
     default:
@@ -2290,7 +2340,11 @@ debug_get_target_type (handle, type)
 {
   if (type == NULL)
     return NULL;
-  type = debug_get_real_type (handle, type);
+
+  type = debug_get_real_type (handle, type, NULL);
+  if (type == NULL)
+    return NULL;
+
   switch (type->kind)
     {
     default:
@@ -2317,7 +2371,11 @@ debug_get_fields (handle, type)
 {
   if (type == NULL)
     return NULL;
-  type = debug_get_real_type (handle, type);
+
+  type = debug_get_real_type (handle, type, NULL);
+  if (type == NULL)
+    return NULL;
+
   switch (type->kind)
     {
     default:
@@ -2333,10 +2391,9 @@ debug_get_fields (handle, type)
 
 /* Get the type of a field.  */
 
-/*ARGSUSED*/
 debug_type
 debug_get_field_type (handle, field)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_field field;
 {
   if (field == NULL)
@@ -2346,10 +2403,9 @@ debug_get_field_type (handle, field)
 
 /* Get the name of a field.  */
 
-/*ARGSUSED*/
 const char *
 debug_get_field_name (handle, field)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_field field;
 {
   if (field == NULL)
@@ -2359,10 +2415,9 @@ debug_get_field_name (handle, field)
 
 /* Get the bit position of a field.  */
 
-/*ARGSUSED*/
 bfd_vma
 debug_get_field_bitpos (handle, field)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_field field;
 {
   if (field == NULL || field->static_member)
@@ -2372,10 +2427,9 @@ debug_get_field_bitpos (handle, field)
 
 /* Get the bit size of a field.  */
 
-/*ARGSUSED*/
 bfd_vma
 debug_get_field_bitsize (handle, field)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_field field;
 {
   if (field == NULL || field->static_member)
@@ -2385,10 +2439,9 @@ debug_get_field_bitsize (handle, field)
 
 /* Get the visibility of a field.  */
 
-/*ARGSUSED*/
 enum debug_visibility
 debug_get_field_visibility (handle, field)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_field field;
 {
   if (field == NULL)
@@ -2400,7 +2453,7 @@ debug_get_field_visibility (handle, field)
 
 const char *
 debug_get_field_physname (handle, field)
-     PTR handle;
+     PTR handle ATTRIBUTE_UNUSED;
      debug_field field;
 {
   if (field == NULL || ! field->static_member)
@@ -2411,7 +2464,7 @@ debug_get_field_physname (handle, field)
 /* Write out the debugging information.  This is given a handle to
    debugging information, and a set of function pointers to call.  */
 
-boolean
+bfd_boolean
 debug_write (handle, fns, fhandle)
      PTR handle;
      const struct debug_write_fns *fns;
@@ -2438,56 +2491,42 @@ debug_write (handle, fns, fhandle)
   for (u = info->units; u != NULL; u = u->next)
     {
       struct debug_file *f;
-      boolean first_file;
-      struct debug_lineno *l;
+      bfd_boolean first_file;
+
+      info->current_write_lineno = u->linenos;
+      info->current_write_lineno_index = 0;
 
       if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
-       return false;
+       return FALSE;
 
-      first_file = true;
+      first_file = TRUE;
       for (f = u->files; f != NULL; f = f->next)
        {
          struct debug_name *n;
 
          if (first_file)
-           first_file = false;
-         else
-           {
-             if (! (*fns->start_source) (fhandle, f->filename))
-               return false;
-           }
+           first_file = FALSE;
+         else if (! (*fns->start_source) (fhandle, f->filename))
+           return FALSE;
 
          if (f->globals != NULL)
-           {
-             for (n = f->globals->list; n != NULL; n = n->next)
-               {
-                 if (! debug_write_name (info, fns, fhandle, n))
-                   return false;
-               }
-           }
+           for (n = f->globals->list; n != NULL; n = n->next)
+             if (! debug_write_name (info, fns, fhandle, n))
+               return FALSE;
        }
 
-      for (l = u->linenos; l != NULL; l = l->next)
-       {
-         unsigned int i;
-
-         for (i = 0; i < DEBUG_LINENO_COUNT; i++)
-           {
-             if (l->linenos[i] == (unsigned long) -1)
-               break;
-             if (! (*fns->lineno) (fhandle, l->file->filename, l->linenos[i],
-                                   l->addrs[i]))
-               return false;
-           }
-       }
+      /* Output any line number information which hasn't already been
+         handled.  */
+      if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
+       return FALSE;
     }
 
-  return true;
+  return TRUE;
 }
 
 /* Write out an element in a namespace.  */
 
-static boolean
+static bfd_boolean
 debug_write_name (info, fns, fhandle, n)
      struct debug_handle *info;
      const struct debug_write_fns *fns;
@@ -2499,16 +2538,16 @@ debug_write_name (info, fns, fhandle, n)
     case DEBUG_OBJECT_TYPE:
       if (! debug_write_type (info, fns, fhandle, n->u.type, n)
          || ! (*fns->typdef) (fhandle, n->name))
-       return false;
-      return true;
+       return FALSE;
+      return TRUE;
     case DEBUG_OBJECT_TAG:
       if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
-       return false;
+       return FALSE;
       return (*fns->tag) (fhandle, n->name);
     case DEBUG_OBJECT_VARIABLE:
       if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
                               n->u.variable->val);
     case DEBUG_OBJECT_FUNCTION:
@@ -2521,12 +2560,12 @@ debug_write_name (info, fns, fhandle, n)
     case DEBUG_OBJECT_TYPED_CONSTANT:
       if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->typed_constant) (fhandle, n->name,
                                     n->u.typed_constant->val);
     default:
       abort ();
-      return false;
+      return FALSE;
     }
   /*NOTREACHED*/
 }
@@ -2537,7 +2576,7 @@ debug_write_name (info, fns, fhandle, n)
    then the name argument is a tag from a DEBUG_KIND_TAGGED type which
    points to this one.  */
 
-static boolean
+static bfd_boolean
 debug_write_type (info, fns, fhandle, type, name)
      struct debug_handle *info;
      const struct debug_write_fns *fns;
@@ -2547,7 +2586,7 @@ debug_write_type (info, fns, fhandle, type, name)
 {
   unsigned int i;
   int is;
-  const char *tag;
+  const char *tag = NULL;
 
   /* If we have a name for this type, just output it.  We only output
      typedef names after they have been defined.  We output type tags
@@ -2565,7 +2604,9 @@ debug_write_type (info, fns, fhandle, type, name)
          struct debug_type *real;
          unsigned int id;
 
-         real = debug_get_real_type ((PTR) info, type);
+         real = debug_get_real_type ((PTR) info, type, NULL);
+         if (real == NULL)
+           return (*fns->empty_type) (fhandle);
          id = 0;
          if ((real->kind == DEBUG_KIND_STRUCT
               || real->kind == DEBUG_KIND_UNION
@@ -2578,7 +2619,7 @@ debug_write_type (info, fns, fhandle, type, name)
                  if (! debug_set_class_id (info,
                                            type->u.knamed->name->name,
                                            real))
-                   return false;
+                   return FALSE;
                }
              id = real->u.kclass->id;
            }
@@ -2595,7 +2636,6 @@ debug_write_type (info, fns, fhandle, type, name)
   if (name != NULL)
     name->mark = info->mark;
 
-  tag = NULL;
   if (name != NULL
       && type->kind != DEBUG_KIND_NAMED
       && type->kind != DEBUG_KIND_TAGGED)
@@ -2607,8 +2647,8 @@ debug_write_type (info, fns, fhandle, type, name)
   switch (type->kind)
     {
     case DEBUG_KIND_ILLEGAL:
-      debug_error ("debug_write_type: illegal type encountered");
-      return false;
+      debug_error (_("debug_write_type: illegal type encountered"));
+      return FALSE;
     case DEBUG_KIND_INDIRECT:
       if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
        return (*fns->empty_type) (fhandle);
@@ -2631,7 +2671,7 @@ debug_write_type (info, fns, fhandle, type, name)
          if (type->u.kclass->id <= info->base_id)
            {
              if (! debug_set_class_id (info, tag, type))
-               return false;
+               return FALSE;
            }
 
          if (info->mark == type->u.kclass->mark)
@@ -2652,7 +2692,7 @@ debug_write_type (info, fns, fhandle, type, name)
                                        : 0),
                                       type->kind == DEBUG_KIND_STRUCT,
                                       type->size))
-       return false;
+       return FALSE;
       if (type->u.kclass != NULL
          && type->u.kclass->fields != NULL)
        {
@@ -2665,7 +2705,7 @@ debug_write_type (info, fns, fhandle, type, name)
                                      (struct debug_name *) NULL)
                  || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
                                             f->u.f.bitsize, f->visibility))
-               return false;
+               return FALSE;
            }
        }
       return (*fns->end_struct_type) (fhandle);
@@ -2681,9 +2721,13 @@ debug_write_type (info, fns, fhandle, type, name)
     case DEBUG_KIND_POINTER:
       if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->pointer_type) (fhandle);
     case DEBUG_KIND_FUNCTION:
+      if (! debug_write_type (info, fns, fhandle,
+                             type->u.kfunction->return_type,
+                             (struct debug_name *) NULL))
+       return FALSE;
       if (type->u.kfunction->arg_types == NULL)
        is = -1;
       else
@@ -2692,23 +2736,19 @@ debug_write_type (info, fns, fhandle, type, name)
            if (! debug_write_type (info, fns, fhandle,
                                    type->u.kfunction->arg_types[is],
                                    (struct debug_name *) NULL))
-             return false;
+             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, is,
                                    type->u.kfunction->varargs);
     case DEBUG_KIND_REFERENCE:
       if (! debug_write_type (info, fns, fhandle, type->u.kreference,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->reference_type) (fhandle);
     case DEBUG_KIND_RANGE:
       if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->range_type) (fhandle, type->u.krange->lower,
                                 type->u.krange->upper);
     case DEBUG_KIND_ARRAY:
@@ -2717,14 +2757,14 @@ debug_write_type (info, fns, fhandle, type, name)
          || ! debug_write_type (info, fns, fhandle,
                                 type->u.karray->range_type,
                                 (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->array_type) (fhandle, type->u.karray->lower,
                                 type->u.karray->upper,
                                 type->u.karray->stringp);
     case DEBUG_KIND_SET:
       if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
     case DEBUG_KIND_OFFSET:
       if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
@@ -2732,13 +2772,13 @@ debug_write_type (info, fns, fhandle, type, name)
          || ! debug_write_type (info, fns, fhandle,
                                 type->u.koffset->target_type,
                                 (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->offset_type) (fhandle);
     case DEBUG_KIND_METHOD:
       if (! debug_write_type (info, fns, fhandle,
                              type->u.kmethod->return_type,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       if (type->u.kmethod->arg_types == NULL)
        is = -1;
       else
@@ -2747,14 +2787,14 @@ debug_write_type (info, fns, fhandle, type, name)
            if (! debug_write_type (info, fns, fhandle,
                                    type->u.kmethod->arg_types[is],
                                    (struct debug_name *) NULL))
-             return false;
+             return FALSE;
        }
       if (type->u.kmethod->domain_type != NULL)
        {
          if (! debug_write_type (info, fns, fhandle,
                                  type->u.kmethod->domain_type,
                                  (struct debug_name *) NULL))
-           return false;
+           return FALSE;
        }
       return (*fns->method_type) (fhandle,
                                  type->u.kmethod->domain_type != NULL,
@@ -2763,12 +2803,12 @@ debug_write_type (info, fns, fhandle, type, name)
     case DEBUG_KIND_CONST:
       if (! debug_write_type (info, fns, fhandle, type->u.kconst,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->const_type) (fhandle);
     case DEBUG_KIND_VOLATILE:
       if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
                              (struct debug_name *) NULL))
-       return false;
+       return FALSE;
       return (*fns->volatile_type) (fhandle);
     case DEBUG_KIND_NAMED:
       return debug_write_type (info, fns, fhandle, type->u.knamed->type,
@@ -2778,13 +2818,13 @@ debug_write_type (info, fns, fhandle, type, name)
                               type->u.knamed->name);
     default:
       abort ();
-      return false;
+      return FALSE;
     }
 }
 
 /* Write out a class type.  */
 
-static boolean
+static bfd_boolean
 debug_write_class_type (info, fns, fhandle, type, tag)
      struct debug_handle *info;
      const struct debug_write_fns *fns;
@@ -2806,7 +2846,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
       if (type->u.kclass->id <= info->base_id)
        {
          if (! debug_set_class_id (info, tag, type))
-           return false;
+           return FALSE;
        }
 
       if (info->mark == type->u.kclass->mark)
@@ -2826,7 +2866,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
        {
          if (! debug_write_type (info, fns, fhandle, vptrbase,
                                  (struct debug_name *) NULL))
-           return false;
+           return FALSE;
        }
     }
 
@@ -2835,7 +2875,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
                                  type->size,
                                  vptrbase != NULL,
                                  vptrbase == type))
-    return false;
+    return FALSE;
 
   if (type->u.kclass != NULL)
     {
@@ -2848,19 +2888,19 @@ debug_write_class_type (info, fns, fhandle, type, tag)
              f = type->u.kclass->fields[i];
              if (! debug_write_type (info, fns, fhandle, f->type,
                                      (struct debug_name *) NULL))
-               return false;
+               return FALSE;
              if (f->static_member)
                {
                  if (! (*fns->class_static_member) (fhandle, f->name,
                                                     f->u.s.physname,
                                                     f->visibility))
-                   return false;
+                   return FALSE;
                }
              else
                {
                  if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
                                              f->u.f.bitsize, f->visibility))
-                   return false;
+                   return FALSE;
                }
            }
        }
@@ -2874,10 +2914,10 @@ debug_write_class_type (info, fns, fhandle, type, tag)
              b = type->u.kclass->baseclasses[i];
              if (! debug_write_type (info, fns, fhandle, b->type,
                                      (struct debug_name *) NULL))
-               return false;
+               return FALSE;
              if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
                                             b->visibility))
-               return false;
+               return FALSE;
            }
        }
 
@@ -2890,7 +2930,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
 
              m = type->u.kclass->methods[i];
              if (! (*fns->class_start_method) (fhandle, m->name))
-               return false;
+               return FALSE;
              for (j = 0; m->variants[j] != NULL; j++)
                {
                  struct debug_method_variant *v;
@@ -2900,11 +2940,11 @@ debug_write_class_type (info, fns, fhandle, type, tag)
                    {
                      if (! debug_write_type (info, fns, fhandle, v->context,
                                              (struct debug_name *) NULL))
-                       return false;
+                       return FALSE;
                    }
                  if (! debug_write_type (info, fns, fhandle, v->type,
                                          (struct debug_name *) NULL))
-                   return false;
+                   return FALSE;
                  if (v->voffset != VOFFSET_STATIC_METHOD)
                    {
                      if (! (*fns->class_method_variant) (fhandle, v->physname,
@@ -2913,7 +2953,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
                                                          v->volatilep,
                                                          v->voffset,
                                                          v->context != NULL))
-                       return false;
+                       return FALSE;
                    }
                  else
                    {
@@ -2922,11 +2962,11 @@ debug_write_class_type (info, fns, fhandle, type, tag)
                                                                 v->visibility,
                                                                 v->constp,
                                                                 v->volatilep))
-                       return false;
+                       return FALSE;
                    }
                }
              if (! (*fns->class_end_method) (fhandle))
-               return false;
+               return FALSE;
            }
        }
     }
@@ -2936,7 +2976,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
 
 /* Write out information for a function.  */
 
-static boolean
+static bfd_boolean
 debug_write_function (info, fns, fhandle, name, linkage, function)
      struct debug_handle *info;
      const struct debug_write_fns *fns;
@@ -2948,26 +2988,29 @@ debug_write_function (info, fns, fhandle, name, linkage, function)
   struct debug_parameter *p;
   struct debug_block *b;
 
+  if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
+    return FALSE;
+
   if (! debug_write_type (info, fns, fhandle, function->return_type,
                          (struct debug_name *) NULL))
-    return false;
+    return FALSE;
 
   if (! (*fns->start_function) (fhandle, name,
                                linkage == DEBUG_LINKAGE_GLOBAL))
-    return false;
+    return FALSE;
 
   for (p = function->parameters; p != NULL; p = p->next)
     {
       if (! debug_write_type (info, fns, fhandle, p->type,
                              (struct debug_name *) NULL)
          || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
-       return false;
+       return FALSE;
     }
 
   for (b = function->blocks; b != NULL; b = b->next)
     {
       if (! debug_write_block (info, fns, fhandle, b))
-       return false;
+       return FALSE;
     }
 
   return (*fns->end_function) (fhandle);
@@ -2975,7 +3018,7 @@ debug_write_function (info, fns, fhandle, name, linkage, function)
 
 /* Write out information for a block.  */
 
-static boolean
+static bfd_boolean
 debug_write_block (info, fns, fhandle, block)
      struct debug_handle *info;
      const struct debug_write_fns *fns;
@@ -2985,12 +3028,15 @@ debug_write_block (info, fns, fhandle, block)
   struct debug_name *n;
   struct debug_block *b;
 
+  if (! debug_write_linenos (info, fns, fhandle, block->start))
+    return FALSE;
+
   /* I can't see any point to writing out a block with no local
      variables, so we don't bother, except for the top level block.  */
   if (block->locals != NULL || block->parent == NULL)
     {
       if (! (*fns->start_block) (fhandle, block->start))
-       return false;
+       return FALSE;
     }
 
   if (block->locals != NULL)
@@ -2998,23 +3044,65 @@ debug_write_block (info, fns, fhandle, block)
       for (n = block->locals->list; n != NULL; n = n->next)
        {
          if (! debug_write_name (info, fns, fhandle, n))
-           return false;
+           return FALSE;
        }
     }
 
   for (b = block->children; b != NULL; b = b->next)
     {
       if (! debug_write_block (info, fns, fhandle, b))
-       return false;
+       return FALSE;
     }
 
+  if (! debug_write_linenos (info, fns, fhandle, block->end))
+    return FALSE;
+
   if (block->locals != NULL || block->parent == NULL)
     {
       if (! (*fns->end_block) (fhandle, block->end))
-       return false;
+       return FALSE;
     }
 
-  return true;
+  return TRUE;
+}
+
+/* Write out line number information up to ADDRESS.  */
+
+static bfd_boolean
+debug_write_linenos (info, fns, fhandle, address)
+     struct debug_handle *info;
+     const struct debug_write_fns *fns;
+     PTR fhandle;
+     bfd_vma address;
+{
+  while (info->current_write_lineno != NULL)
+    {
+      struct debug_lineno *l;
+
+      l = info->current_write_lineno;
+
+      while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
+       {
+         if (l->linenos[info->current_write_lineno_index]
+             == (unsigned long) -1)
+           break;
+
+         if (l->addrs[info->current_write_lineno_index] >= address)
+           return TRUE;
+
+         if (! (*fns->lineno) (fhandle, l->file->filename,
+                               l->linenos[info->current_write_lineno_index],
+                               l->addrs[info->current_write_lineno_index]))
+           return FALSE;
+
+         ++info->current_write_lineno_index;
+       }
+
+      info->current_write_lineno = l->next;
+      info->current_write_lineno_index = 0;
+    }
+
+  return TRUE;
 }
 
 /* Get the ID number for a class.  If during the same call to
@@ -3022,7 +3110,7 @@ debug_write_block (info, fns, fhandle, block)
    name, we use the same ID.  This type of things happens because the
    same struct will be defined by multiple compilation units.  */
 
-static boolean
+static bfd_boolean
 debug_set_class_id (info, tag, type)
      struct debug_handle *info;
      const char *tag;
@@ -3039,7 +3127,7 @@ debug_set_class_id (info, tag, type)
   c = type->u.kclass;
 
   if (c->id > info->base_id)
-    return true;
+    return TRUE;
 
   for (l = info->id_list; l != NULL; l = l->next)
     {
@@ -3062,7 +3150,7 @@ debug_set_class_id (info, tag, type)
       if (debug_type_samep (info, l->type, type))
        {
          c->id = l->type->u.kclass->id;
-         return true;
+         return TRUE;
        }
     }
 
@@ -3080,13 +3168,13 @@ debug_set_class_id (info, tag, type)
   l->next = info->id_list;
   info->id_list = l;
 
-  return true;
+  return TRUE;
 }
 
 /* See if two types are the same.  At this point, we don't care about
    tags and the like.  */
 
-static boolean
+static bfd_boolean
 debug_type_samep (info, t1, t2)
      struct debug_handle *info;
      struct debug_type *t1;
@@ -3094,23 +3182,28 @@ debug_type_samep (info, t1, t2)
 {
   struct debug_type_compare_list *l;
   struct debug_type_compare_list top;
-  boolean ret;
+  bfd_boolean ret;
+
+  if (t1 == NULL)
+    return t2 == NULL;
+  if (t2 == NULL)
+    return FALSE;
 
   while (t1->kind == DEBUG_KIND_INDIRECT)
     {
       t1 = *t1->u.kindirect->slot;
       if (t1 == NULL)
-       return false;
+       return FALSE;
     }
   while (t2->kind == DEBUG_KIND_INDIRECT)
     {
       t2 = *t2->u.kindirect->slot;
       if (t2 == NULL)
-       return false;
+       return FALSE;
     }
 
   if (t1 == t2)
-    return true;
+    return TRUE;
 
   /* As a special case, permit a typedef to match a tag, since C++
      debugging output will sometimes add a typedef where C debugging
@@ -3124,7 +3217,7 @@ debug_type_samep (info, t1, t2)
 
   if (t1->kind != t2->kind
       || t1->size != t2->size)
-    return false;
+    return FALSE;
 
   /* Get rid of the trivial cases first.  */
   switch (t1->kind)
@@ -3135,7 +3228,7 @@ debug_type_samep (info, t1, t2)
     case DEBUG_KIND_FLOAT:
     case DEBUG_KIND_COMPLEX:
     case DEBUG_KIND_BOOL:
-      return true;
+      return TRUE;
     case DEBUG_KIND_INT:
       return t1->u.kint == t2->u.kint;
     }
@@ -3147,7 +3240,7 @@ debug_type_samep (info, t1, t2)
   for (l = info->compare_list; l != NULL; l = l->next)
     {
       if (l->t1 == t1 && l->t2 == t2)
-       return true;
+       return TRUE;
     }
 
   top.t1 = t1;
@@ -3159,7 +3252,7 @@ debug_type_samep (info, t1, t2)
     {
     default:
       abort ();
-      ret = false;
+      ret = FALSE;
       break;
 
     case DEBUG_KIND_STRUCT:
@@ -3169,10 +3262,10 @@ debug_type_samep (info, t1, t2)
       if (t1->u.kclass == NULL)
        ret = t2->u.kclass == NULL;
       else if (t2->u.kclass == NULL)
-       ret = false;
+       ret = FALSE;
       else if (t1->u.kclass->id > info->base_id
               && t1->u.kclass->id == t2->u.kclass->id)
-       ret = true;
+       ret = TRUE;
       else
        ret = debug_class_type_samep (info, t1, t2);
       break;
@@ -3181,7 +3274,7 @@ debug_type_samep (info, t1, t2)
       if (t1->u.kenum == NULL)
        ret = t2->u.kenum == NULL;
       else if (t2->u.kenum == NULL)
-       ret = false;
+       ret = FALSE;
       else
        {
          const char **pn1, **pn2;
@@ -3199,6 +3292,8 @@ debug_type_samep (info, t1, t2)
                break;
              ++pn1;
              ++pn2;
+             ++pv1;
+             ++pv2;
            }
          ret = *pn1 == NULL && *pn2 == NULL;
        }
@@ -3207,16 +3302,16 @@ debug_type_samep (info, t1, t2)
     case DEBUG_KIND_POINTER:
       ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
       break;
-            
+
     case DEBUG_KIND_FUNCTION:
       if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
          || ! debug_type_samep (info, t1->u.kfunction->return_type,
                                 t2->u.kfunction->return_type)
          || ((t1->u.kfunction->arg_types == NULL)
              != (t2->u.kfunction->arg_types == NULL)))
-       ret = false;
+       ret = FALSE;
       else if (t1->u.kfunction->arg_types == NULL)
-       ret = true;
+       ret = TRUE;
       else
        {
          struct debug_type **a1, **a2;
@@ -3224,8 +3319,12 @@ debug_type_samep (info, t1, t2)
          a1 = t1->u.kfunction->arg_types;
          a2 = t2->u.kfunction->arg_types;
          while (*a1 != NULL && *a2 != NULL)
-           if (! debug_type_samep (info, *a1, *a2))
-             break;
+           {
+             if (! debug_type_samep (info, *a1, *a2))
+               break;
+             ++a1;
+             ++a2;
+           }
          ret = *a1 == NULL && *a2 == NULL;
        }
       break;
@@ -3268,9 +3367,9 @@ debug_type_samep (info, t1, t2)
                                 t2->u.kmethod->domain_type)
          || ((t1->u.kmethod->arg_types == NULL)
              != (t2->u.kmethod->arg_types == NULL)))
-       ret = false;
+       ret = FALSE;
       else if (t1->u.kmethod->arg_types == NULL)
-       ret = true;
+       ret = TRUE;
       else
        {
          struct debug_type **a1, **a2;
@@ -3278,8 +3377,12 @@ debug_type_samep (info, t1, t2)
          a1 = t1->u.kmethod->arg_types;
          a2 = t2->u.kmethod->arg_types;
          while (*a1 != NULL && *a2 != NULL)
-           if (! debug_type_samep (info, *a1, *a2))
-             break;
+           {
+             if (! debug_type_samep (info, *a1, *a2))
+               break;
+             ++a1;
+             ++a2;
+           }
          ret = *a1 == NULL && *a2 == NULL;
        }
       break;
@@ -3308,7 +3411,7 @@ debug_type_samep (info, t1, t2)
 /* See if two classes are the same.  This is a subroutine of
    debug_type_samep.  */
 
-static boolean
+static bfd_boolean
 debug_class_type_samep (info, t1, t2)
      struct debug_handle *info;
      struct debug_type *t1;
@@ -3323,7 +3426,7 @@ debug_class_type_samep (info, t1, t2)
       || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
       || (c1->methods == NULL) != (c2->methods == NULL)
       || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
-    return false;
+    return FALSE;
 
   if (c1->fields != NULL)
     {
@@ -3340,17 +3443,17 @@ debug_class_type_samep (info, t1, t2)
          if (f1->name[0] != f2->name[0]
              || f1->visibility != f2->visibility
              || f1->static_member != f2->static_member)
-           return false;
+           return FALSE;
          if (f1->static_member)
            {
              if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
-               return false;
+               return FALSE;
            }
          else
            {
              if (f1->u.f.bitpos != f2->u.f.bitpos
                  || f1->u.f.bitsize != f2->u.f.bitsize)
-               return false;
+               return FALSE;
            }
          /* We do the checks which require function calls last.  We
              don't require that the types of fields have the same
@@ -3359,19 +3462,19 @@ debug_class_type_samep (info, t1, t2)
          if (strcmp (f1->name, f2->name) != 0
              || ! debug_type_samep (info,
                                     debug_get_real_type ((PTR) info,
-                                                         f1->type),
+                                                         f1->type, NULL),
                                     debug_get_real_type ((PTR) info,
-                                                         f2->type)))
-           return false;
+                                                         f2->type, NULL)))
+           return FALSE;
        }
       if (*pf1 != NULL || *pf2 != NULL)
-       return false;
+       return FALSE;
     }
 
   if (c1->vptrbase != NULL)
     {
       if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
-       return false;
+       return FALSE;
     }
 
   if (c1->baseclasses != NULL)
@@ -3390,10 +3493,10 @@ debug_class_type_samep (info, t1, t2)
              || b1->virtual != b2->virtual
              || b1->visibility != b2->visibility
              || ! debug_type_samep (info, b1->type, b2->type))
-           return false;
+           return FALSE;
        }
       if (*pb1 != NULL || *pb2 != NULL)
-       return false;
+       return FALSE;
     }
 
   if (c1->methods != NULL)
@@ -3411,7 +3514,7 @@ debug_class_type_samep (info, t1, t2)
          if (m1->name[0] != m2->name[0]
              || strcmp (m1->name, m2->name) != 0
              || (m1->variants == NULL) != (m2->variants == NULL))
-           return false;
+           return FALSE;
          if (m1->variants == NULL)
            {
              struct debug_method_variant **pv1, **pv2;
@@ -3432,21 +3535,21 @@ debug_class_type_samep (info, t1, t2)
                      || (v1->context == NULL) != (v2->context == NULL)
                      || strcmp (v1->physname, v2->physname) != 0
                      || ! debug_type_samep (info, v1->type, v2->type))
-                   return false;
+                   return FALSE;
                  if (v1->context != NULL)
                    {
                      if (! debug_type_samep (info, v1->context,
                                              v2->context))
-                       return false;
+                       return FALSE;
                    }
                }
              if (*pv1 != NULL || *pv2 != NULL)
-               return false;
+               return FALSE;
            }
        }
       if (*pm1 != NULL || *pm2 != NULL)
-       return false;
+       return FALSE;
     }
 
-  return true;
+  return TRUE;
 }