Handle DW_FORM_implicit_const when displaying an attribute
[deliverable/binutils-gdb.git] / binutils / stabs.c
index 558fe0eeceae2feb64d10c0c5e70eb0ec8ce50ee..274bfb0e7fa23319859c7e5a795cd3d5b8aed49f 100644 (file)
@@ -1,13 +1,12 @@
 /* stabs.c -- Parse stabs debugging information
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+   Copyright (C) 1995-2021 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /* This file contains code which parses stabs debugging information.
    The organization of this code is based on the gdb stabs reading
    code.  The job it does is somewhat different, because it is not
    trying to identify the correct address for anything.  */
 
-#include <stdio.h>
-
+#include "sysdep.h"
 #include "bfd.h"
-#include "bucomm.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
 #include "demangle.h"
@@ -50,7 +47,7 @@ struct stab_handle
   /* The BFD.  */
   bfd *abfd;
   /* TRUE if this is stabs in sections.  */
-  bfd_boolean sections;
+  bool sections;
   /* The symbol table.  */
   asymbol **syms;
   /* The number of symbols.  */
@@ -70,7 +67,7 @@ struct stab_handle
   int gcc_compiled;
   /* Whether an N_OPT symbol was seen that was not generated by gcc,
      so that we can detect the SunPRO compiler.  */
-  bfd_boolean n_opt_found;
+  bool n_opt_found;
   /* The main file name.  */
   char *main_filename;
   /* A stack of unfinished N_BINCL files.  */
@@ -78,7 +75,7 @@ struct stab_handle
   /* A list of finished N_BINCL files.  */
   struct bincl_file *bincl_list;
   /* Whether we are inside a function or not.  */
-  bfd_boolean within_function;
+  bool within_function;
   /* The address of the end of the function, used if we have seen an
      N_FUN symbol while in a function.  This is -1 if we have not seen
      an N_FUN (the normal case).  */
@@ -97,7 +94,7 @@ struct stab_handle
   struct stab_tag *tags;
   /* Set by parse_stab_type if it sees a structure defined as a cross
      reference to itself.  Reset by parse_stab_type otherwise.  */
-  bfd_boolean self_crossref;
+  bool self_crossref;
 };
 
 /* A list of these structures is used to hold pending variable
@@ -148,59 +145,77 @@ struct stab_tag
 };
 
 static char *savestring (const char *, int);
-static bfd_vma parse_number (const char **, bfd_boolean *);
+
 static void bad_stab (const char *);
 static void warn_stab (const char *, const char *);
-static bfd_boolean parse_stab_string
-  (void *, struct stab_handle *, int, int, bfd_vma, const char *);
+static bool parse_stab_string
+  (void *, struct stab_handle *, int, int, bfd_vma,
+   const char *, const char *);
 static debug_type parse_stab_type
-  (void *, struct stab_handle *, const char *, const char **, debug_type **);
-static bfd_boolean parse_stab_type_number (const char **, int *);
+  (void *, struct stab_handle *, const char *, const char **,
+   debug_type **, const char *);
+static bool parse_stab_type_number
+  (const char **, int *, const char *);
 static debug_type parse_stab_range_type
-  (void *, struct stab_handle *, const char *, const char **, const int *);
-static debug_type parse_stab_sun_builtin_type (void *, const char **);
-static debug_type parse_stab_sun_floating_type (void *, const char **);
-static debug_type parse_stab_enum_type (void *, const char **);
+  (void *, struct stab_handle *, const char *, const char **,
+   const int *, const char *);
+static debug_type parse_stab_sun_builtin_type
+  (void *, const char **, const char *);
+static debug_type parse_stab_sun_floating_type
+  (void *, const char **, const char *);
+static debug_type parse_stab_enum_type
+  (void *, const char **, const char *);
 static debug_type parse_stab_struct_type
   (void *, struct stab_handle *, const char *, const char **,
-   bfd_boolean, const int *);
-static bfd_boolean parse_stab_baseclasses
-  (void *, struct stab_handle *, const char **, debug_baseclass **);
-static bfd_boolean parse_stab_struct_fields
-  (void *, struct stab_handle *, const char **, debug_field **, bfd_boolean *);
-static bfd_boolean parse_stab_cpp_abbrev
-  (void *, struct stab_handle *, const char **, debug_field *);
-static bfd_boolean parse_stab_one_struct_field
+   bool, const int *, const char *);
+static bool parse_stab_baseclasses
+  (void *, struct stab_handle *, const char **, debug_baseclass **,
+   const char *);
+static bool parse_stab_struct_fields
+  (void *, struct stab_handle *, const char **, debug_field **,
+   bool *, const char *);
+static bool parse_stab_cpp_abbrev
+  (void *, struct stab_handle *, const char **, debug_field *, const char *);
+static bool parse_stab_one_struct_field
   (void *, struct stab_handle *, const char **, const char *,
-   debug_field *, bfd_boolean *);
-static bfd_boolean parse_stab_members
+   debug_field *, bool *, const char *);
+static bool parse_stab_members
   (void *, struct stab_handle *, const char *, const char **, const int *,
-   debug_method **);
+   debug_method **, const char *);
 static debug_type parse_stab_argtypes
   (void *, struct stab_handle *, debug_type, const char *, const char *,
-   debug_type, const char *, bfd_boolean, bfd_boolean, const char **);
-static bfd_boolean parse_stab_tilde_field
+   debug_type, const char *, bool, bool, const char **);
+static bool parse_stab_tilde_field
   (void *, struct stab_handle *, const char **, const int *, debug_type *,
-   bfd_boolean *);
+   bool *, const char *);
 static debug_type parse_stab_array_type
-  (void *, struct stab_handle *, const char **, bfd_boolean);
+  (void *, struct stab_handle *, const char **, bool, const char *);
 static void push_bincl (struct stab_handle *, const char *, bfd_vma);
 static const char *pop_bincl (struct stab_handle *);
-static bfd_boolean find_excl (struct stab_handle *, const char *, bfd_vma);
-static bfd_boolean stab_record_variable
+static bool find_excl (struct stab_handle *, const char *, bfd_vma);
+static bool stab_record_variable
   (void *, struct stab_handle *, const char *, debug_type,
    enum debug_var_kind, bfd_vma);
-static bfd_boolean stab_emit_pending_vars (void *, struct stab_handle *);
+static bool stab_emit_pending_vars (void *, struct stab_handle *);
 static debug_type *stab_find_slot (struct stab_handle *, const int *);
 static debug_type stab_find_type (void *, struct stab_handle *, const int *);
-static bfd_boolean stab_record_type
+static bool stab_record_type
   (void *, struct stab_handle *, const int *, debug_type);
 static debug_type stab_xcoff_builtin_type
   (void *, struct stab_handle *, int);
 static debug_type stab_find_tagged_type
   (void *, struct stab_handle *, const char *, int, enum debug_type_kind);
 static debug_type *stab_demangle_argtypes
-  (void *, struct stab_handle *, const char *, bfd_boolean *, unsigned int);
+  (void *, struct stab_handle *, const char *, bool *, unsigned int);
+static debug_type *stab_demangle_v3_argtypes
+  (void *, struct stab_handle *, const char *, bool *);
+static debug_type *stab_demangle_v3_arglist
+  (void *, struct stab_handle *, struct demangle_component *, bool *);
+static debug_type stab_demangle_v3_arg
+  (void *, struct stab_handle *, struct demangle_component *, debug_type,
+   bool *);
+
+static int demangle_flags = DMGL_ANSI;
 
 /* Save a string in memory.  */
 
@@ -218,15 +233,21 @@ savestring (const char *start, int len)
 /* Read a number from a string.  */
 
 static bfd_vma
-parse_number (const char **pp, bfd_boolean *poverflow)
+parse_number (const char **pp, bool *poverflow, const char *p_end)
 {
   unsigned long ul;
   const char *orig;
 
   if (poverflow != NULL)
-    *poverflow = FALSE;
+    *poverflow = false;
 
   orig = *pp;
+  if (orig >= p_end)
+    return (bfd_vma) 0;
+
+  /* Stop early if we are passed an empty string.  */
+  if (*orig == 0)
+    return (bfd_vma) 0;
 
   errno = 0;
   ul = strtoul (*pp, (char **) pp, 0);
@@ -245,21 +266,21 @@ parse_number (const char **pp, bfd_boolean *poverflow)
   if (sizeof (bfd_vma) > sizeof (unsigned long))
     {
       const char *p;
-      bfd_boolean neg;
+      bool neg;
       int base;
       bfd_vma over, lastdig;
-      bfd_boolean overflow;
+      bool overflow;
       bfd_vma v;
 
       /* Our own version of strtoul, for a bfd_vma.  */
       p = orig;
 
-      neg = FALSE;
+      neg = false;
       if (*p == '+')
        ++p;
       else if (*p == '-')
        {
-         neg = TRUE;
+         neg = true;
          ++p;
        }
 
@@ -281,7 +302,7 @@ parse_number (const char **pp, bfd_boolean *poverflow)
       over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
       lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
 
-      overflow = FALSE;
+      overflow = false;
       v = 0;
       while (1)
        {
@@ -302,7 +323,7 @@ parse_number (const char **pp, bfd_boolean *poverflow)
 
          if (v > over || (v == over && (bfd_vma) d > lastdig))
            {
-             overflow = TRUE;
+             overflow = true;
              break;
            }
        }
@@ -318,7 +339,7 @@ parse_number (const char **pp, bfd_boolean *poverflow)
   /* If we get here, the number is too large to represent in a
      bfd_vma.  */
   if (poverflow != NULL)
-    *poverflow = TRUE;
+    *poverflow = true;
   else
     warn_stab (orig, _("numeric overflow"));
 
@@ -344,7 +365,7 @@ warn_stab (const char *p, const char *err)
 /* Create a handle to parse stabs symbols with.  */
 
 void *
-start_stab (void *dhandle ATTRIBUTE_UNUSED, bfd *abfd, bfd_boolean sections,
+start_stab (void *dhandle ATTRIBUTE_UNUSED, bfd *abfd, bool sections,
            asymbol **syms, long symcount)
 {
   struct stab_handle *ret;
@@ -365,7 +386,7 @@ start_stab (void *dhandle ATTRIBUTE_UNUSED, bfd *abfd, bfd_boolean sections,
 /* When we have processed all the stabs information, we need to go
    through and fill in all the undefined tags.  */
 
-bfd_boolean
+bool
 finish_stab (void *dhandle, void *handle)
 {
   struct stab_handle *info = (struct stab_handle *) handle;
@@ -375,8 +396,8 @@ finish_stab (void *dhandle, void *handle)
     {
       if (! stab_emit_pending_vars (dhandle, info)
          || ! debug_end_function (dhandle, info->function_end))
-       return FALSE;
-      info->within_function = FALSE;
+       return false;
+      info->within_function = false;
       info->function_end = (bfd_vma) -1;
     }
 
@@ -389,18 +410,19 @@ finish_stab (void *dhandle, void *handle)
        kind = DEBUG_KIND_STRUCT;
       st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
       if (st->slot == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Handle a single stabs symbol.  */
 
-bfd_boolean
+bool
 parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
            const char *string)
 {
+  const char * string_end;
   struct stab_handle *info = (struct stab_handle *) handle;
 
   /* gcc will emit two N_SO strings per compilation unit, one for the
@@ -411,11 +433,11 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
       && (type != N_SO || *string == '\0' || value != info->so_value))
     {
       if (! debug_set_filename (dhandle, info->so_string))
-       return FALSE;
+       return false;
       info->main_filename = info->so_string;
 
       info->gcc_compiled = 0;
-      info->n_opt_found = FALSE;
+      info->n_opt_found = false;
 
       /* Generally, for stabs in the symbol table, the N_LBRAC and
         N_RBRAC symbols are relative to the N_SO symbol value.  */
@@ -429,12 +451,13 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
       info->file_types = ((struct stab_types **)
                          xmalloc (sizeof *info->file_types));
       info->file_types[0] = NULL;
-
       info->so_string = NULL;
 
       /* Now process whatever type we just got.  */
     }
 
+  string_end = string + strlen (string);
+
   switch (type)
     {
     case N_FN:
@@ -449,7 +472,7 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
       if (! info->within_function)
        {
          fprintf (stderr, _("N_LBRAC not within function\n"));
-         return FALSE;
+         return false;
        }
 
       /* Start an inner lexical block.  */
@@ -457,11 +480,11 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
                               (value
                                + info->file_start_offset
                                + info->function_start_offset)))
-       return FALSE;
+       return false;
 
       /* Emit any pending variable definitions.  */
       if (! stab_emit_pending_vars (dhandle, info))
-       return FALSE;
+       return false;
 
       ++info->block_depth;
       break;
@@ -475,20 +498,20 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
          if we do, we probably need to emit them before closing the
          block.  */
       if (! stab_emit_pending_vars (dhandle, info))
-       return FALSE;
+       return false;
 
       /* End an inner lexical block.  */
       if (! debug_end_block (dhandle,
                             (value
                              + info->file_start_offset
                              + info->function_start_offset)))
-       return FALSE;
+       return false;
 
       --info->block_depth;
       if (info->block_depth < 0)
        {
          fprintf (stderr, _("Too many N_RBRACs\n"));
-         return FALSE;
+         return false;
        }
       break;
 
@@ -505,15 +528,15 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
            endval = info->function_end;
          if (! stab_emit_pending_vars (dhandle, info)
              || ! debug_end_function (dhandle, endval))
-           return FALSE;
-         info->within_function = FALSE;
+           return false;
+         info->within_function = false;
          info->function_end = (bfd_vma) -1;
        }
 
       /* An empty string is emitted by gcc at the end of a compilation
          unit.  */
       if (*string == '\0')
-       return TRUE;
+       return true;
 
       /* Just accumulate strings until we see a non N_SO symbol.  If
          the string starts with a directory separator or some other
@@ -542,44 +565,44 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
     case N_SOL:
       /* Start an include file.  */
       if (! debug_start_source (dhandle, string))
-       return FALSE;
+       return false;
       break;
 
     case N_BINCL:
       /* Start an include file which may be replaced.  */
       push_bincl (info, string, value);
       if (! debug_start_source (dhandle, string))
-       return FALSE;
+       return false;
       break;
 
     case N_EINCL:
       /* End an N_BINCL include.  */
       if (! debug_start_source (dhandle, pop_bincl (info)))
-       return FALSE;
+       return false;
       break;
 
     case N_EXCL:
       /* This is a duplicate of a header file named by N_BINCL which
          was eliminated by the linker.  */
       if (! find_excl (info, string, value))
-       return FALSE;
+       return false;
       break;
 
     case N_SLINE:
       if (! debug_record_line (dhandle, desc,
                               value + (info->within_function
                                        ? info->function_start_offset : 0)))
-       return FALSE;
+       return false;
       break;
 
     case N_BCOMM:
       if (! debug_start_common_block (dhandle, string))
-       return FALSE;
+       return false;
       break;
 
     case N_ECOMM:
       if (! debug_end_common_block (dhandle, string))
-       return FALSE;
+       return false;
       break;
 
     case N_FUN:
@@ -593,8 +616,8 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
                value += info->function_start_offset;
              if (! stab_emit_pending_vars (dhandle, info)
                  || ! debug_end_function (dhandle, value))
-               return FALSE;
-             info->within_function = FALSE;
+               return false;
+             info->within_function = false;
              info->function_end = (bfd_vma) -1;
            }
          break;
@@ -634,18 +657,18 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
                  endval = info->function_end;
                if (! stab_emit_pending_vars (dhandle, info)
                    || ! debug_end_function (dhandle, endval))
-                 return FALSE;
+                 return false;
                info->function_end = (bfd_vma) -1;
              }
            /* For stabs in sections, line numbers and block addresses
                are offsets from the start of the function.  */
            if (info->sections)
              info->function_start_offset = value;
-           info->within_function = TRUE;
+           info->within_function = true;
          }
 
-       if (! parse_stab_string (dhandle, info, type, desc, value, string))
-         return FALSE;
+       if (! parse_stab_string (dhandle, info, type, desc, value, string, string_end))
+         return false;
       }
       break;
 
@@ -655,7 +678,7 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
       else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
        info->gcc_compiled = 1;
       else
-       info->n_opt_found = TRUE;
+       info->n_opt_found = true;
       break;
 
     case N_OBJ:
@@ -665,27 +688,27 @@ parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value,
       break;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Parse the stabs string.  */
 
-static bfd_boolean
+static bool
 parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
-                  int desc, bfd_vma value, const char *string)
+                  int desc ATTRIBUTE_UNUSED, bfd_vma value,
+                  const char *string, const char * string_end)
 {
   const char *p;
   char *name;
   int type;
   debug_type dtype;
-  bfd_boolean synonym;
-  bfd_boolean self_crossref;
-  unsigned int lineno;
+  bool synonym;
+  bool self_crossref;
   debug_type *slot;
 
   p = strchr (string, ':');
   if (p == NULL)
-    return TRUE;
+    return true;
 
   while (p[1] == ':')
     {
@@ -694,18 +717,10 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
       if (p == NULL)
        {
          bad_stab (string);
-         return FALSE;
+         return false;
        }
     }
 
-  /* GCC 2.x puts the line number in desc.  SunOS apparently puts in
-     the number of bytes occupied by a type or object, which we
-     ignore.  */
-  if (info->gcc_compiled >= 2)
-    lineno = desc;
-  else
-    lineno = 0;
-
   /* FIXME: Sometimes the special C++ names start with '.'.  */
   name = NULL;
   if (string[0] == '$')
@@ -744,6 +759,11 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
   ++p;
   if (ISDIGIT (*p) || *p == '(' || *p == '-')
     type = 'l';
+  else if (*p == 0)
+    {
+      bad_stab (string);
+      return false;
+    }
   else
     type = *p++;
 
@@ -759,7 +779,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
       if (*p != '=')
        {
          bad_stab (string);
-         return FALSE;
+         return false;
        }
       ++p;
       switch (*p++)
@@ -767,7 +787,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
        case 'r':
          /* Floating point constant.  */
          if (! debug_record_float_const (dhandle, name, atof (p)))
-           return FALSE;
+           return false;
          break;
        case 'i':
          /* Integer constant.  */
@@ -778,7 +798,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
             other languages probably should have at least unsigned as
             well as signed constants.  */
          if (! debug_record_int_const (dhandle, name, atoi (p)))
-           return FALSE;
+           return false;
          break;
        case 'e':
          /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
@@ -786,20 +806,20 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
             e.g. "b:c=e6,0" for "const b = blob1"
             (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
          dtype = parse_stab_type (dhandle, info, (const char *) NULL,
-                                  &p, (debug_type **) NULL);
+                                  &p, (debug_type **) NULL, string_end);
          if (dtype == DEBUG_TYPE_NULL)
-           return FALSE;
+           return false;
          if (*p != ',')
            {
              bad_stab (string);
-             return FALSE;
+             return false;
            }
          if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
-           return FALSE;
+           return false;
          break;
        default:
          bad_stab (string);
-         return FALSE;
+         return false;
        }
 
       break;
@@ -807,22 +827,22 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
     case 'C':
       /* The name of a caught exception.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL,
-                              &p, (debug_type **) NULL);
+                              &p, (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! debug_record_label (dhandle, name, dtype, value))
-       return FALSE;
+       return false;
       break;
 
     case 'f':
     case 'F':
       /* A function definition.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
-       return FALSE;
+       return false;
 
       /* Sun acc puts declared types of arguments here.  We don't care
         about their actual types (FIXME -- we should remember the whole
@@ -832,41 +852,47 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
        {
          ++p;
          if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL)
+                              (debug_type **) NULL, string_end)
              == DEBUG_TYPE_NULL)
-           return FALSE;
+           return false;
        }
 
       break;
 
     case 'G':
       {
-       char leading;
-       long c;
        asymbol **ps;
 
        /* A global symbol.  The value must be extracted from the
           symbol table.  */
        dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                                (debug_type **) NULL);
+                                (debug_type **) NULL, string_end);
        if (dtype == DEBUG_TYPE_NULL)
-         return FALSE;
-       leading = bfd_get_symbol_leading_char (info->abfd);
-       for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+         return false;
+       if (name != NULL)
          {
-           const char *n;
+           char leading;
+           long c;
 
-           n = bfd_asymbol_name (*ps);
-           if (leading != '\0' && *n == leading)
-             ++n;
-           if (*n == *name && strcmp (n, name) == 0)
-             break;
+           leading = bfd_get_symbol_leading_char (info->abfd);
+           for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+             {
+               const char *n;
+
+               n = bfd_asymbol_name (*ps);
+               if (leading != '\0' && *n == leading)
+                 ++n;
+               if (*n == *name && strcmp (n, name) == 0)
+                 break;
+             }
+
+           if (c > 0)
+             value = bfd_asymbol_value (*ps);
          }
-       if (c > 0)
-         value = bfd_asymbol_value (*ps);
+
        if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
                                    value))
-         return FALSE;
+         return false;
       }
       break;
 
@@ -876,19 +902,19 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
     case 'l':
     case 's':
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
                                  value))
-       return FALSE;
+       return false;
       break;
 
     case 'p':
       /* A function parameter.  */
       if (*p != 'F')
        dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                                (debug_type **) NULL);
+                                (debug_type **) NULL, string_end);
       else
        {
        /* pF is a two-letter code that means a function parameter in
@@ -896,21 +922,21 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
           value.  Translate it into a pointer-to-function type.  */
          ++p;
          dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                                  (debug_type **) NULL);
+                                  (debug_type **) NULL, string_end);
          if (dtype != DEBUG_TYPE_NULL)
            {
              debug_type ftype;
 
              ftype = debug_make_function_type (dhandle, dtype,
-                                               (debug_type *) NULL, FALSE);
+                                               (debug_type *) NULL, false);
              dtype = debug_make_pointer_type (dhandle, ftype);
            }
        }
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
                                    value))
-       return FALSE;
+       return false;
 
       /* FIXME: At this point gdb considers rearranging the parameter
         address on a big endian machine if it is smaller than an int.
@@ -926,9 +952,9 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
            {
              ++p;
              if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                                  (debug_type **) NULL)
+                                  (debug_type **) NULL, string_end)
                  == DEBUG_TYPE_NULL)
-               return FALSE;
+               return false;
            }
          break;
        }
@@ -936,23 +962,23 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
     case 'R':
       /* Parameter which is in a register.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
                                    value))
-       return FALSE;
+       return false;
       break;
 
     case 'r':
       /* Register variable (either global or local).  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
                                  value))
-       return FALSE;
+       return false;
 
       /* FIXME: At this point gdb checks to combine pairs of 'p' and
         'r' stabs into a single 'P' stab.  */
@@ -961,28 +987,28 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
     case 'S':
       /* Static symbol at top level of file.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
                                  value))
-       return FALSE;
+       return false;
       break;
 
     case 't':
       /* A typedef.  */
-      dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+      dtype = parse_stab_type (dhandle, info, name, &p, &slot, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (name == NULL)
        {
          /* A nameless type.  Nothing to do.  */
-         return TRUE;
+         return true;
        }
 
       dtype = debug_name_type (dhandle, name, dtype);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
 
       if (slot != NULL)
        *slot = dtype;
@@ -990,25 +1016,25 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
       break;
 
     case 'T':
-      /* Struct, union, or enum tag.  For GNU C++, this can be be followed
+      /* Struct, union, or enum tag.  For GNU C++, this can be followed
         by 't' which means we are typedef'ing it as well.  */
       if (*p != 't')
        {
-         synonym = FALSE;
+         synonym = false;
          /* FIXME: gdb sets synonym to TRUE if the current language
              is C++.  */
        }
       else
        {
-         synonym = TRUE;
+         synonym = true;
          ++p;
        }
 
-      dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+      dtype = parse_stab_type (dhandle, info, name, &p, &slot, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (name == NULL)
-       return TRUE;
+       return true;
 
       /* INFO->SELF_CROSSREF is set by parse_stab_type if this type is
          a cross reference to itself.  These are generated by some
@@ -1017,7 +1043,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
 
       dtype = debug_tag_type (dhandle, name, dtype);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (slot != NULL)
        *slot = dtype;
 
@@ -1044,7 +1070,7 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
        {
          dtype = debug_name_type (dhandle, name, dtype);
          if (dtype == DEBUG_TYPE_NULL)
-           return FALSE;
+           return false;
 
          if (slot != NULL)
            *slot = dtype;
@@ -1055,35 +1081,35 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
     case 'V':
       /* Static symbol of local scope */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       /* FIXME: gdb checks os9k_stabs here.  */
       if (! stab_record_variable (dhandle, info, name, dtype,
                                  DEBUG_LOCAL_STATIC, value))
-       return FALSE;
+       return false;
       break;
 
     case 'v':
       /* Reference parameter.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
                                    value))
-       return FALSE;
+       return false;
       break;
 
     case 'a':
       /* Reference parameter which is in a register.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
                                    value))
-       return FALSE;
+       return false;
       break;
 
     case 'X':
@@ -1092,23 +1118,43 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
         that Pascal uses it too, but when I tried it Pascal used
         "x:3" (local symbol) instead.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, string_end);
       if (dtype == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
       if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
                                  value))
-       return FALSE;
+       return false;
       break;
 
+    case 'Y':
+      /* SUNPro C++ Namespace =Yn0.  */
+      /* Skip the namespace mapping, as it is not used now.  */
+      if (*(++p) == 'n' && *(++p) == '0')
+       {
+         /* =Yn0name; */
+         while (*p != ';')
+           ++p;
+         ++p;
+         return true;
+       }
+      /* TODO SUNPro C++ support:
+         Support default arguments after F,P parameters
+         Ya = Anonymous unions
+         YM,YD = Pointers to class members
+         YT,YI = Templates
+         YR = Run-time type information (RTTI)  */
+
+      /* Fall through.  */
+
     default:
       bad_stab (string);
-      return FALSE;
+      return false;
     }
 
   /* FIXME: gdb converts structure values to structure pointers in a
      couple of cases, depending upon the target.  */
 
-  return TRUE;
+  return true;
 }
 
 /* Parse a stabs type.  The typename argument is non-NULL if this is a
@@ -1117,12 +1163,17 @@ parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype,
    store the slot used if the type is being defined.  */
 
 static debug_type
-parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename, const char **pp, debug_type **slotp)
+parse_stab_type (void *                dhandle,
+                struct stab_handle *  info,
+                const char *          type_name,
+                const char **         pp,
+                debug_type **         slotp,
+                const char *          p_end)
 {
   const char *orig;
   int typenums[2];
   int size;
-  bfd_boolean stringp;
+  bool stringp;
   int descriptor;
   debug_type dtype;
 
@@ -1130,11 +1181,13 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
     *slotp = NULL;
 
   orig = *pp;
+  if (orig >= p_end)
+    return DEBUG_TYPE_NULL;
 
   size = -1;
-  stringp = FALSE;
+  stringp = false;
 
-  info->self_crossref = FALSE;
+  info->self_crossref = false;
 
   /* Read type number if present.  The type number may be omitted.
      for instance in a two-dimensional array declared with type
@@ -1147,7 +1200,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
     }
   else
     {
-      if (! parse_stab_type_number (pp, typenums))
+      if (! parse_stab_type_number (pp, typenums, p_end))
        return DEBUG_TYPE_NULL;
 
       if (**pp != '=')
@@ -1207,9 +1260,13 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
              break;
 
            case 'S':
-             stringp = TRUE;
+             stringp = true;
              break;
 
+           case 0:
+             bad_stab (orig);
+             return DEBUG_TYPE_NULL;
+
            default:
              /* Ignore unrecognized type attributes, so future
                 compilers can invent new ones.  */
@@ -1240,6 +1297,10 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
          case 'e':
            code = DEBUG_KIND_ENUM;
            break;
+         case 0:
+             bad_stab (orig);
+             return DEBUG_TYPE_NULL;
+           
          default:
            /* Complain and keep going, so compilers can invent new
               cross-reference types.  */
@@ -1281,10 +1342,10 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
               fleep:T20=xsfleep:
           which define structures in terms of themselves.  We need to
           tell the caller to avoid building a circular structure.  */
-       if (typename != NULL
-           && strncmp (typename, *pp, p - *pp) == 0
-           && typename[p - *pp] == '\0')
-         info->self_crossref = TRUE;
+       if (type_name != NULL
+           && strncmp (type_name, *pp, p - *pp) == 0
+           && type_name[p - *pp] == '\0')
+         info->self_crossref = true;
 
        dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
 
@@ -1313,7 +1374,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
        hold = *pp;
 
        /* Peek ahead at the number to detect void.  */
-       if (! parse_stab_type_number (pp, xtypenums))
+       if (! parse_stab_type_number (pp, xtypenums, p_end))
          return DEBUG_TYPE_NULL;
 
        if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
@@ -1330,7 +1391,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
               This means that we can deal with something like
               t(1,2)=(3,4)=... which the Lucid compiler uses.  */
            dtype = parse_stab_type (dhandle, info, (const char *) NULL,
-                                    pp, (debug_type **) NULL);
+                                    pp, (debug_type **) NULL, p_end);
            if (dtype == DEBUG_TYPE_NULL)
              return DEBUG_TYPE_NULL;
          }
@@ -1349,7 +1410,8 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
                                       parse_stab_type (dhandle, info,
                                                        (const char *) NULL,
                                                        pp,
-                                                       (debug_type **) NULL));
+                                                       (debug_type **) NULL,
+                                                       p_end));
       break;
 
     case '&':
@@ -1357,7 +1419,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
       dtype = (debug_make_reference_type
               (dhandle,
                parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                (debug_type **) NULL)));
+                                (debug_type **) NULL, p_end)));
       break;
 
     case 'f':
@@ -1366,8 +1428,8 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
       dtype = (debug_make_function_type
               (dhandle,
                parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                (debug_type **) NULL),
-               (debug_type *) NULL, FALSE));
+                                (debug_type **) NULL, p_end),
+               (debug_type *) NULL, false));
       break;
 
     case 'k':
@@ -1377,7 +1439,8 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
                                     parse_stab_type (dhandle, info,
                                                      (const char *) NULL,
                                                      pp,
-                                                     (debug_type **) NULL));
+                                                     (debug_type **) NULL,
+                                                     p_end));
       break;
 
     case 'B':
@@ -1386,7 +1449,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
       dtype = (debug_make_volatile_type
               (dhandle,
                parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                (debug_type **) NULL)));
+                                (debug_type **) NULL, p_end)));
       break;
 
     case '@':
@@ -1399,7 +1462,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
        /* Member type.  */
 
        domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                 (debug_type **) NULL);
+                                 (debug_type **) NULL, p_end);
        if (domain == DEBUG_TYPE_NULL)
          return DEBUG_TYPE_NULL;
 
@@ -1411,7 +1474,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
        ++*pp;
 
        memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                  (debug_type **) NULL);
+                                  (debug_type **) NULL, p_end);
        if (memtype == DEBUG_TYPE_NULL)
          return DEBUG_TYPE_NULL;
 
@@ -1427,7 +1490,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
 
          ++*pp;
          return_type = parse_stab_type (dhandle, info, (const char *) NULL,
-                                        pp, (debug_type **) NULL);
+                                        pp, (debug_type **) NULL, p_end);
          if (return_type == DEBUG_TYPE_NULL)
            return DEBUG_TYPE_NULL;
          if (**pp != ';')
@@ -1438,7 +1501,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
          ++*pp;
          dtype = debug_make_method_type (dhandle, return_type,
                                          DEBUG_TYPE_NULL,
-                                         (debug_type *) NULL, FALSE);
+                                         (debug_type *) NULL, false);
        }
       else
        {
@@ -1447,10 +1510,10 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
          debug_type *args;
          unsigned int n;
          unsigned int alloc;
-         bfd_boolean varargs;
+         bool varargs;
 
          domain = parse_stab_type (dhandle, info, (const char *) NULL,
-                                   pp, (debug_type **) NULL);
+                                   pp, (debug_type **) NULL, p_end);
          if (domain == DEBUG_TYPE_NULL)
            return DEBUG_TYPE_NULL;
 
@@ -1462,7 +1525,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
          ++*pp;
 
          return_type = parse_stab_type (dhandle, info, (const char *) NULL,
-                                        pp, (debug_type **) NULL);
+                                        pp, (debug_type **) NULL, p_end);
          if (return_type == DEBUG_TYPE_NULL)
            return DEBUG_TYPE_NULL;
 
@@ -1486,7 +1549,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
                }
 
              args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
-                                        pp, (debug_type **) NULL);
+                                        pp, (debug_type **) NULL, p_end);
              if (args[n] == DEBUG_TYPE_NULL)
                return DEBUG_TYPE_NULL;
              ++n;
@@ -1498,11 +1561,11 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
             the void type.  */
          if (n == 0
              || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
-           varargs = TRUE;
+           varargs = true;
          else
            {
              --n;
-             varargs = FALSE;
+             varargs = false;
            }
 
          args[n] = DEBUG_TYPE_NULL;
@@ -1514,30 +1577,30 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
 
     case 'r':
       /* Range type.  */
-      dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
+      dtype = parse_stab_range_type (dhandle, info, type_name, pp, typenums, p_end);
       break;
 
     case 'b':
       /* FIXME: gdb checks os9k_stabs here.  */
       /* Sun ACC builtin int type.  */
-      dtype = parse_stab_sun_builtin_type (dhandle, pp);
+      dtype = parse_stab_sun_builtin_type (dhandle, pp, p_end);
       break;
 
     case 'R':
       /* Sun ACC builtin float type.  */
-      dtype = parse_stab_sun_floating_type (dhandle, pp);
+      dtype = parse_stab_sun_floating_type (dhandle, pp, p_end);
       break;
 
     case 'e':
       /* Enumeration type.  */
-      dtype = parse_stab_enum_type (dhandle, pp);
+      dtype = parse_stab_enum_type (dhandle, pp, p_end);
       break;
 
     case 's':
     case 'u':
       /* Struct or union type.  */
-      dtype = parse_stab_struct_type (dhandle, info, typename, pp,
-                                     descriptor == 's', typenums);
+      dtype = parse_stab_struct_type (dhandle, info, type_name, pp,
+                                     descriptor == 's', typenums, p_end);
       break;
 
     case 'a':
@@ -1549,7 +1612,7 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
        }
       ++*pp;
 
-      dtype = parse_stab_array_type (dhandle, info, pp, stringp);
+      dtype = parse_stab_array_type (dhandle, info, pp, stringp, p_end);
       break;
 
     case 'S':
@@ -1557,7 +1620,8 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
                                   parse_stab_type (dhandle, info,
                                                    (const char *) NULL,
                                                    pp,
-                                                   (debug_type **) NULL),
+                                                   (debug_type **) NULL,
+                                                   p_end),
                                   stringp);
       break;
 
@@ -1589,8 +1653,8 @@ parse_stab_type (void *dhandle, struct stab_handle *info, const char *typename,
    single number N is equivalent to (0,N).  Return the two numbers by
    storing them in the vector TYPENUMS.  */
 
-static bfd_boolean
-parse_stab_type_number (const char **pp, int *typenums)
+static bool
+parse_stab_type_number (const char **pp, int *typenums, const char *p_end)
 {
   const char *orig;
 
@@ -1599,50 +1663,57 @@ parse_stab_type_number (const char **pp, int *typenums)
   if (**pp != '(')
     {
       typenums[0] = 0;
-      typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
+      typenums[1] = (int) parse_number (pp, (bool *) NULL, p_end);
+      return true;
     }
-  else
+
+  ++*pp;
+  typenums[0] = (int) parse_number (pp, (bool *) NULL, p_end);
+  if (**pp != ',')
     {
-      ++*pp;
-      typenums[0] = (int) parse_number (pp, (bfd_boolean *) NULL);
-      if (**pp != ',')
-       {
-         bad_stab (orig);
-         return FALSE;
-       }
-      ++*pp;
-      typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
-      if (**pp != ')')
-       {
-         bad_stab (orig);
-         return FALSE;
-       }
-      ++*pp;
+      bad_stab (orig);
+      return false;
     }
 
-  return TRUE;
+  ++*pp;
+  typenums[1] = (int) parse_number (pp, (bool *) NULL, p_end);
+  if (**pp != ')')
+    {
+      bad_stab (orig);
+      return false;
+    }
+
+  ++*pp;
+  return true;
 }
 
 /* Parse a range type.  */
 
 static debug_type
-parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *typename, const char **pp, const int *typenums)
+parse_stab_range_type (void *                dhandle,
+                      struct stab_handle *  info,
+                      const char *          type_name,
+                      const char **         pp,
+                      const int *           typenums,
+                      const char *          p_end)
 {
   const char *orig;
   int rangenums[2];
-  bfd_boolean self_subrange;
+  bool self_subrange;
   debug_type index_type;
   const char *s2, *s3;
   bfd_signed_vma n2, n3;
-  bfd_boolean ov2, ov3;
+  bool ov2, ov3;
 
   orig = *pp;
+  if (orig >= p_end)
+    return DEBUG_TYPE_NULL;
 
   index_type = DEBUG_TYPE_NULL;
 
   /* First comes a type we are a subrange of.
      In C it is usually 0, 1 or the type being defined.  */
-  if (! parse_stab_type_number (pp, rangenums))
+  if (! parse_stab_type_number (pp, rangenums, p_end))
     return DEBUG_TYPE_NULL;
 
   self_subrange = (rangenums[0] == typenums[0]
@@ -1652,7 +1723,7 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
     {
       *pp = orig;
       index_type = parse_stab_type (dhandle, info, (const char *) NULL,
-                                   pp, (debug_type **) NULL);
+                                   pp, (debug_type **) NULL, p_end);
       if (index_type == DEBUG_TYPE_NULL)
        return DEBUG_TYPE_NULL;
     }
@@ -1663,7 +1734,7 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
   /* The remaining two operands are usually lower and upper bounds of
      the range.  But in some special cases they mean something else.  */
   s2 = *pp;
-  n2 = parse_number (pp, &ov2);
+  n2 = parse_number (pp, &ov2, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -1672,7 +1743,7 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
   ++*pp;
 
   s3 = *pp;
-  n3 = parse_number (pp, &ov3);
+  n3 = parse_number (pp, &ov3, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -1689,13 +1760,13 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
 #define ULLHIGH "01777777777777777777777;"
       if (index_type == DEBUG_TYPE_NULL)
        {
-         if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
-             && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
-           return debug_make_int_type (dhandle, 8, FALSE);
+         if (startswith (s2, LLLOW)
+             && startswith (s3, LLHIGH))
+           return debug_make_int_type (dhandle, 8, false);
          if (! ov2
              && n2 == 0
-             && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
-           return debug_make_int_type (dhandle, 8, TRUE);
+             && startswith (s3, ULLHIGH))
+           return debug_make_int_type (dhandle, 8, true);
        }
 
       warn_stab (orig, _("numeric overflow"));
@@ -1725,53 +1796,53 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
                 long long int:t6=r1;0;-1;
                 long long unsigned int:t7=r1;0;-1;
             We hack here to handle this reasonably.  */
-         if (typename != NULL)
+         if (type_name != NULL)
            {
-             if (strcmp (typename, "long long int") == 0)
-               return debug_make_int_type (dhandle, 8, FALSE);
-             else if (strcmp (typename, "long long unsigned int") == 0)
-               return debug_make_int_type (dhandle, 8, TRUE);
+             if (strcmp (type_name, "long long int") == 0)
+               return debug_make_int_type (dhandle, 8, false);
+             else if (strcmp (type_name, "long long unsigned int") == 0)
+               return debug_make_int_type (dhandle, 8, true);
            }
          /* FIXME: The size here really depends upon the target.  */
-         return debug_make_int_type (dhandle, 4, TRUE);
+         return debug_make_int_type (dhandle, 4, true);
        }
 
       /* A range of 0 to 127 is char.  */
       if (self_subrange && n2 == 0 && n3 == 127)
-       return debug_make_int_type (dhandle, 1, FALSE);
+       return debug_make_int_type (dhandle, 1, false);
 
       /* FIXME: gdb checks for the language CHILL here.  */
 
       if (n2 == 0)
        {
          if (n3 < 0)
-           return debug_make_int_type (dhandle, - n3, TRUE);
+           return debug_make_int_type (dhandle, - n3, true);
          else if (n3 == 0xff)
-           return debug_make_int_type (dhandle, 1, TRUE);
+           return debug_make_int_type (dhandle, 1, true);
          else if (n3 == 0xffff)
-           return debug_make_int_type (dhandle, 2, TRUE);
+           return debug_make_int_type (dhandle, 2, true);
          else if (n3 == (bfd_signed_vma) 0xffffffff)
-           return debug_make_int_type (dhandle, 4, TRUE);
+           return debug_make_int_type (dhandle, 4, true);
 #ifdef BFD64
-         else if (n3 == ((((bfd_signed_vma) 0xffffffff) << 32) | 0xffffffff))
-           return debug_make_int_type (dhandle, 8, TRUE);
+         else if (n3 == (bfd_signed_vma) 0xffffffffffffffffLL)
+           return debug_make_int_type (dhandle, 8, true);
 #endif
        }
       else if (n3 == 0
               && n2 < 0
               && (self_subrange || n2 == -8))
-       return debug_make_int_type (dhandle, - n2, TRUE);
+       return debug_make_int_type (dhandle, - n2, true);
       else if (n2 == - n3 - 1 || n2 == n3 + 1)
        {
          if (n3 == 0x7f)
-           return debug_make_int_type (dhandle, 1, FALSE);
+           return debug_make_int_type (dhandle, 1, false);
          else if (n3 == 0x7fff)
-           return debug_make_int_type (dhandle, 2, FALSE);
+           return debug_make_int_type (dhandle, 2, false);
          else if (n3 == 0x7fffffff)
-           return debug_make_int_type (dhandle, 4, FALSE);
+           return debug_make_int_type (dhandle, 4, false);
 #ifdef BFD64
          else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff))
-           return debug_make_int_type (dhandle, 8, FALSE);
+           return debug_make_int_type (dhandle, 8, false);
 #endif
        }
     }
@@ -1791,7 +1862,7 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
       /* Does this actually ever happen?  Is that why we are worrying
          about dealing with it rather than just calling error_type?  */
       warn_stab (orig, _("missing index type"));
-      index_type = debug_make_int_type (dhandle, 4, FALSE);
+      index_type = debug_make_int_type (dhandle, 4, false);
     }
 
   return debug_make_range_type (dhandle, index_type, n2, n3);
@@ -1810,21 +1881,23 @@ parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type
    FIXME.  */
 
 static debug_type
-parse_stab_sun_builtin_type (void *dhandle, const char **pp)
+parse_stab_sun_builtin_type (void *dhandle, const char **pp, const char * p_end)
 {
   const char *orig;
-  bfd_boolean unsignedp;
+  bool unsignedp;
   bfd_vma bits;
 
   orig = *pp;
+  if (orig >= p_end)
+    return DEBUG_TYPE_NULL;
 
   switch (**pp)
     {
     case 's':
-      unsignedp = FALSE;
+      unsignedp = false;
       break;
     case 'u':
-      unsignedp = TRUE;
+      unsignedp = true;
       break;
     default:
       bad_stab (orig);
@@ -1832,18 +1905,20 @@ parse_stab_sun_builtin_type (void *dhandle, const char **pp)
     }
   ++*pp;
 
-  /* For some odd reason, all forms of char put a c here.  This is strange
-     because no other type has this honor.  We can safely ignore this because
-     we actually determine 'char'acterness by the number of bits specified in
-     the descriptor.  */
-  if (**pp == 'c')
+  /* OpenSolaris source code indicates that one of "cbv" characters
+     can come next and specify the intrinsic 'iformat' encoding.
+     'c' is character encoding, 'b' is boolean encoding, and 'v' is
+     varargs encoding.  This field can be safely ignored because
+     the type of the field is determined from the bitwidth extracted
+     below.  */
+  if (**pp == 'c' || **pp == 'b' || **pp == 'v')
     ++*pp;
 
   /* The first number appears to be the number of bytes occupied
      by this type, except that unsigned short is 4 instead of 2.
      Since this information is redundant with the third number,
      we will ignore it.  */
-  (void) parse_number (pp, (bfd_boolean *) NULL);
+  (void) parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -1852,7 +1927,7 @@ parse_stab_sun_builtin_type (void *dhandle, const char **pp)
   ++*pp;
 
   /* The second number is always 0, so ignore it too.  */
-  (void) parse_number (pp, (bfd_boolean *) NULL);
+  (void) parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -1861,7 +1936,7 @@ parse_stab_sun_builtin_type (void *dhandle, const char **pp)
   ++*pp;
 
   /* The third number is the number of bits for this type.  */
-  bits = parse_number (pp, (bfd_boolean *) NULL);
+  bits = parse_number (pp, (bool *) NULL, p_end);
 
   /* The type *should* end with a semicolon.  If it are embedded
      in a larger type the semicolon may be the only way to know where
@@ -1881,17 +1956,19 @@ parse_stab_sun_builtin_type (void *dhandle, const char **pp)
 /* Parse a builtin floating type generated by the Sun compiler.  */
 
 static debug_type
-parse_stab_sun_floating_type (void *dhandle, const char **pp)
+parse_stab_sun_floating_type (void *dhandle, const char **pp, const char *p_end)
 {
   const char *orig;
   bfd_vma details;
   bfd_vma bytes;
 
   orig = *pp;
+  if (orig >= p_end)
+    return DEBUG_TYPE_NULL;
 
   /* The first number has more details about the type, for example
      FN_COMPLEX.  */
-  details = parse_number (pp, (bfd_boolean *) NULL);
+  details = parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -1899,7 +1976,7 @@ parse_stab_sun_floating_type (void *dhandle, const char **pp)
     }
 
   /* The second number is the number of bytes occupied by this type */
-  bytes = parse_number (pp, (bfd_boolean *) NULL);
+  bytes = parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -1917,7 +1994,7 @@ parse_stab_sun_floating_type (void *dhandle, const char **pp)
 /* Handle an enum type.  */
 
 static debug_type
-parse_stab_enum_type (void *dhandle, const char **pp)
+parse_stab_enum_type (void *dhandle, const char **pp, const char * p_end)
 {
   const char *orig;
   const char **names;
@@ -1926,6 +2003,8 @@ parse_stab_enum_type (void *dhandle, const char **pp)
   unsigned int alloc;
 
   orig = *pp;
+  if (orig >= p_end)
+    return DEBUG_TYPE_NULL;
 
   /* FIXME: gdb checks os9k_stabs here.  */
 
@@ -1933,8 +2012,14 @@ parse_stab_enum_type (void *dhandle, const char **pp)
      my guess is it's a type of some sort.  Just ignore it.  */
   if (**pp == '-')
     {
-      while (**pp != ':')
+      while (**pp != ':' && **pp != 0)
        ++*pp;
+
+      if (**pp == 0)
+       {
+         bad_stab (orig);
+         return DEBUG_TYPE_NULL;
+       }
       ++*pp;
     }
 
@@ -1952,16 +2037,27 @@ parse_stab_enum_type (void *dhandle, const char **pp)
       bfd_signed_vma val;
 
       p = *pp;
-      while (*p != ':')
+      while (*p != ':' && *p != 0)
        ++p;
 
+      if (*p == 0)
+       {
+         bad_stab (orig);
+         free (names);
+         free (values);
+         return DEBUG_TYPE_NULL;
+       }
+
       name = savestring (*pp, p - *pp);
 
       *pp = p + 1;
-      val = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
+      val = (bfd_signed_vma) parse_number (pp, (bool *) NULL, p_end);
       if (**pp != ',')
        {
          bad_stab (orig);
+         free (name);
+         free (names);
+         free (values);
          return DEBUG_TYPE_NULL;
        }
       ++*pp;
@@ -1997,31 +2093,35 @@ parse_stab_enum_type (void *dhandle, const char **pp)
    *PP will point to "4a:1,0,32;;".  */
 
 static debug_type
-parse_stab_struct_type (void *dhandle, struct stab_handle *info,
-                       const char *tagname, const char **pp,
-                       bfd_boolean structp, const int *typenums)
+parse_stab_struct_type (void *dhandle,
+                       struct stab_handle *info,
+                       const char *tagname,
+                       const char **pp,
+                       bool structp,
+                       const int *typenums,
+                       const char *p_end)
 {
-  const char *orig;
   bfd_vma size;
   debug_baseclass *baseclasses;
-  debug_field *fields;
-  bfd_boolean statics;
+  debug_field *fields = NULL;
+  bool statics;
   debug_method *methods;
   debug_type vptrbase;
-  bfd_boolean ownvptr;
-
-  orig = *pp;
+  bool ownvptr;
 
   /* Get the size.  */
-  size = parse_number (pp, (bfd_boolean *) NULL);
+  size = parse_number (pp, (bool *) NULL, p_end);
 
   /* Get the other information.  */
-  if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
-      || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
-      || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
+  if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses, p_end)
+      || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics, p_end)
+      || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods, p_end)
       || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
-                                  &ownvptr))
-    return DEBUG_TYPE_NULL;
+                                  &ownvptr, p_end))
+    {
+      free (fields);
+      return DEBUG_TYPE_NULL;
+    }
 
   if (! statics
       && baseclasses == NULL
@@ -2058,9 +2158,12 @@ parse_stab_struct_type (void *dhandle, struct stab_handle *info,
 
   Return TRUE for success, FALSE for failure.  */
 
-static bfd_boolean
-parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
-                       const char **pp, debug_baseclass **retp)
+static bool
+parse_stab_baseclasses (void *                dhandle,
+                       struct stab_handle *  info,
+                       const char **         pp,
+                       debug_baseclass **    retp,
+                       const char *          p_end)
 {
   const char *orig;
   unsigned int c, i;
@@ -2069,20 +2172,22 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
   *retp = NULL;
 
   orig = *pp;
+  if (orig >= p_end)
+    return false;
 
   if (**pp != '!')
     {
       /* No base classes.  */
-      return TRUE;
+      return true;
     }
   ++*pp;
 
-  c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL);
+  c = (unsigned int) parse_number (pp, (bool *) NULL, p_end);
 
   if (**pp != ',')
     {
       bad_stab (orig);
-      return FALSE;
+      return false;
     }
   ++*pp;
 
@@ -2090,7 +2195,7 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
 
   for (i = 0; i < c; i++)
     {
-      bfd_boolean virtual;
+      bool is_virtual;
       enum debug_visibility visibility;
       bfd_vma bitpos;
       debug_type type;
@@ -2098,14 +2203,17 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
       switch (**pp)
        {
        case '0':
-         virtual = FALSE;
+         is_virtual = false;
          break;
        case '1':
-         virtual = TRUE;
+         is_virtual = true;
          break;
+       case 0:
+         bad_stab (orig);
+         return false;
        default:
          warn_stab (orig, _("unknown virtual character for baseclass"));
-         virtual = FALSE;
+         is_virtual = false;
          break;
        }
       ++*pp;
@@ -2121,6 +2229,9 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
        case '2':
          visibility = DEBUG_VISIBILITY_PUBLIC;
          break;
+       case 0:
+         bad_stab (orig);
+         return false;
        default:
          warn_stab (orig, _("unknown visibility character for baseclass"));
          visibility = DEBUG_VISIBILITY_PUBLIC;
@@ -2131,26 +2242,26 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
       /* The remaining value is the bit offset of the portion of the
         object corresponding to this baseclass.  Always zero in the
         absence of multiple inheritance.  */
-      bitpos = parse_number (pp, (bfd_boolean *) NULL);
+      bitpos = parse_number (pp, (bool *) NULL, p_end);
       if (**pp != ',')
        {
          bad_stab (orig);
-         return FALSE;
+         return false;
        }
       ++*pp;
 
       type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                             (debug_type **) NULL);
+                             (debug_type **) NULL, p_end);
       if (type == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
 
-      classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
+      classes[i] = debug_make_baseclass (dhandle, type, bitpos, is_virtual,
                                         visibility);
       if (classes[i] == DEBUG_BASECLASS_NULL)
-       return FALSE;
+       return false;
 
       if (**pp != ';')
-       return FALSE;
+       return false;
       ++*pp;
     }
 
@@ -2158,7 +2269,7 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
 
   *retp = classes;
 
-  return TRUE;
+  return true;
 }
 
 /* Read struct or class data fields.  They have the form:
@@ -2181,10 +2292,13 @@ parse_stab_baseclasses (void *dhandle, struct stab_handle *info,
 
    Returns 1 for success, 0 for failure.  */
 
-static bfd_boolean
-parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
-                         const char **pp, debug_field **retp,
-                         bfd_boolean *staticsp)
+static bool
+parse_stab_struct_fields (void *dhandle,
+                         struct stab_handle *info,
+                         const char **pp,
+                         debug_field **retp,
+                         bool *staticsp,
+                         const char * p_end)
 {
   const char *orig;
   const char *p;
@@ -2193,9 +2307,11 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
   unsigned int alloc;
 
   *retp = NULL;
-  *staticsp = FALSE;
+  *staticsp = false;
 
   orig = *pp;
+  if (orig >= p_end)
+    return false;
 
   c = 0;
   alloc = 10;
@@ -2224,8 +2340,11 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
       if ((*p == '$' || *p == '.') && p[1] != '_')
        {
          ++*pp;
-         if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
-           return FALSE;
+         if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c, p_end))
+           {
+             free (fields);
+             return false;
+           }
          ++c;
          continue;
        }
@@ -2239,15 +2358,16 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
       if (p == NULL)
        {
          bad_stab (orig);
-         return FALSE;
+         free (fields);
+         return false;
        }
 
       if (p[1] == ':')
        break;
 
       if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
-                                        staticsp))
-       return FALSE;
+                                        staticsp, p_end))
+       return false;
 
       ++c;
     }
@@ -2256,35 +2376,45 @@ parse_stab_struct_fields (void *dhandle, struct stab_handle *info,
 
   *retp = fields;
 
-  return TRUE;
+  return true;
 }
 
 /* Special GNU C++ name.  */
 
-static bfd_boolean
-parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
-                      const char **pp, debug_field *retp)
+static bool
+parse_stab_cpp_abbrev (void *                dhandle,
+                      struct stab_handle *  info,
+                      const char **         pp,
+                      debug_field *         retp,
+                      const char *          p_end)
 {
   const char *orig;
   int cpp_abbrev;
   debug_type context;
   const char *name;
-  const char *typename;
+  const char *type_name;
   debug_type type;
   bfd_vma bitpos;
 
   *retp = DEBUG_FIELD_NULL;
 
   orig = *pp;
+  if (orig >= p_end)
+    return false;
 
   if (**pp != 'v')
     {
       bad_stab (*pp);
-      return FALSE;
+      return false;
     }
   ++*pp;
 
   cpp_abbrev = **pp;
+  if (cpp_abbrev == 0)
+    {
+      bad_stab (orig);
+      return false;
+    }
   ++*pp;
 
   /* At this point, *pp points to something like "22:23=*22...", where
@@ -2293,9 +2423,9 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
      name, and construct the field name.  */
 
   context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                            (debug_type **) NULL);
+                            (debug_type **) NULL, p_end);
   if (context == DEBUG_TYPE_NULL)
-    return FALSE;
+    return false;
 
   switch (cpp_abbrev)
     {
@@ -2305,13 +2435,13 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
       break;
     case 'b':
       /* $vb -- a virtual bsomethingorother */
-      typename = debug_get_type_name (dhandle, context);
-      if (typename == NULL)
+      type_name = debug_get_type_name (dhandle, context);
+      if (type_name == NULL)
        {
          warn_stab (orig, _("unnamed $vb type"));
-         typename = "FOO";
+         type_name = "FOO";
        }
-      name = concat ("_vb$", typename, (const char *) NULL);
+      name = concat ("_vb$", type_name, (const char *) NULL);
       break;
     default:
       warn_stab (orig, _("unrecognized C++ abbreviation"));
@@ -2322,41 +2452,45 @@ parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info,
   if (**pp != ':')
     {
       bad_stab (orig);
-      return FALSE;
+      return false;
     }
   ++*pp;
 
   type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                         (debug_type **) NULL);
+                         (debug_type **) NULL, p_end);
   if (**pp != ',')
     {
       bad_stab (orig);
-      return FALSE;
+      return false;
     }
   ++*pp;
 
-  bitpos = parse_number (pp, (bfd_boolean *) NULL);
+  bitpos = parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
-      return FALSE;
+      return false;
     }
   ++*pp;
 
   *retp = debug_make_field (dhandle, name, type, bitpos, 0,
                            DEBUG_VISIBILITY_PRIVATE);
   if (*retp == DEBUG_FIELD_NULL)
-    return FALSE;
+    return false;
 
-  return TRUE;
+  return true;
 }
 
 /* Parse a single field in a struct or union.  */
 
-static bfd_boolean
-parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
-                            const char **pp, const char *p,
-                            debug_field *retp, bfd_boolean *staticsp)
+static bool
+parse_stab_one_struct_field (void *dhandle,
+                            struct stab_handle *info,
+                            const char **pp,
+                            const char *p,
+                            debug_field *retp,
+                            bool *staticsp,
+                            const char *p_end)
 {
   const char *orig;
   char *name;
@@ -2366,6 +2500,8 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
   bfd_vma bitsize;
 
   orig = *pp;
+  if (orig >= p_end)
+    return false;
 
   /* FIXME: gdb checks ARM_DEMANGLING here.  */
 
@@ -2389,6 +2525,9 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
        case '2':
          visibility = DEBUG_VISIBILITY_PUBLIC;
          break;
+       case 0:
+         bad_stab (orig);
+         return false;
        default:
          warn_stab (orig, _("unknown visibility character for field"));
          visibility = DEBUG_VISIBILITY_PUBLIC;
@@ -2398,9 +2537,12 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
     }
 
   type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                         (debug_type **) NULL);
+                         (debug_type **) NULL, p_end);
   if (type == DEBUG_TYPE_NULL)
-    return FALSE;
+    {
+      free (name);
+      return false;
+    }
 
   if (**pp == ':')
     {
@@ -2412,7 +2554,8 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
       if (p == NULL)
        {
          bad_stab (orig);
-         return FALSE;
+         free (name);
+         return false;
        }
 
       varname = savestring (*pp, p - *pp);
@@ -2421,31 +2564,34 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
 
       *retp = debug_make_static_member (dhandle, name, type, varname,
                                        visibility);
-      *staticsp = TRUE;
+      *staticsp = true;
 
-      return TRUE;
+      return true;
     }
 
   if (**pp != ',')
     {
       bad_stab (orig);
-      return FALSE;
+      free (name);
+      return false;
     }
   ++*pp;
 
-  bitpos = parse_number (pp, (bfd_boolean *) NULL);
+  bitpos = parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ',')
     {
       bad_stab (orig);
-      return FALSE;
+      free (name);
+      return false;
     }
   ++*pp;
 
-  bitsize = parse_number (pp, (bfd_boolean *) NULL);
+  bitsize = parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
-      return FALSE;
+      free (name);
+      return false;
     }
   ++*pp;
 
@@ -2471,7 +2617,7 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
 
   *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);
 
-  return TRUE;
+  return true;
 }
 
 /* Read member function stabs info for C++ classes.  The form of each member
@@ -2487,19 +2633,28 @@ parse_stab_one_struct_field (void *dhandle, struct stab_handle *info,
    $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
    name (such as `+=') and `.' marks the end of the operator name.  */
 
-static bfd_boolean
-parse_stab_members (void *dhandle, struct stab_handle *info,
-                   const char *tagname, const char **pp,
-                   const int *typenums, debug_method **retp)
+static bool
+parse_stab_members (void *                dhandle,
+                   struct stab_handle *  info,
+                   const char *          tagname,
+                   const char **         pp,
+                   const int *           typenums,
+                   debug_method **       retp,
+                   const char *          p_end)
 {
   const char *orig;
   debug_method *methods;
   unsigned int c;
   unsigned int alloc;
+  char *name = NULL;
+  debug_method_variant *variants = NULL;
+  char *argtypes = NULL;
 
   *retp = NULL;
 
   orig = *pp;
+  if (orig >= p_end)
+    return false;
 
   alloc = 0;
   methods = NULL;
@@ -2508,8 +2663,6 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
   while (**pp != ';')
     {
       const char *p;
-      char *name;
-      debug_method_variant *variants;
       unsigned int cvars;
       unsigned int allocvars;
       debug_type look_ahead_type;
@@ -2538,7 +2691,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
          if (*p != '.')
            {
              bad_stab (orig);
-             return FALSE;
+             goto fail;
            }
          name = savestring (*pp, p - *pp);
          *pp = p + 1;
@@ -2554,14 +2707,13 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
       do
        {
          debug_type type;
-         bfd_boolean stub;
-         char *argtypes;
+         bool stub;
          enum debug_visibility visibility;
-         bfd_boolean constp, volatilep, staticp;
+         bool constp, volatilep, staticp;
          bfd_vma voffset;
          debug_type context;
          const char *physname;
-         bfd_boolean varargs;
+         bool varargs;
 
          if (look_ahead_type != DEBUG_TYPE_NULL)
            {
@@ -2572,13 +2724,14 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
          else
            {
              type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                     (debug_type **) NULL);
+                                     (debug_type **) NULL, p_end);
              if (type == DEBUG_TYPE_NULL)
-               return FALSE;
+               goto fail;
+
              if (**pp != ':')
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
            }
 
@@ -2587,13 +2740,13 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
          if (p == NULL)
            {
              bad_stab (orig);
-             return FALSE;
+             goto fail;
            }
 
-         stub = FALSE;
+         stub = false;
          if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
              && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
-           stub = TRUE;
+           stub = true;
 
          argtypes = savestring (*pp, p - *pp);
          *pp = p + 1;
@@ -2606,14 +2759,17 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
            case '1':
              visibility = DEBUG_VISIBILITY_PROTECTED;
              break;
+           case 0:
+             bad_stab (orig);
+             goto fail;
            default:
              visibility = DEBUG_VISIBILITY_PUBLIC;
              break;
            }
          ++*pp;
 
-         constp = FALSE;
-         volatilep = FALSE;
+         constp = false;
+         volatilep = false;
          switch (**pp)
            {
            case 'A':
@@ -2622,18 +2778,18 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
              break;
            case 'B':
              /* const member function.  */
-             constp = TRUE;
+             constp = true;
              ++*pp;
              break;
            case 'C':
              /* volatile member function.  */
-             volatilep = TRUE;
+             volatilep = true;
              ++*pp;
              break;
            case 'D':
              /* const volatile member function.  */
-             constp = TRUE;
-             volatilep = TRUE;
+             constp = true;
+             volatilep = true;
              ++*pp;
              break;
            case '*':
@@ -2646,24 +2802,24 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
              break;
            }
 
-         staticp = FALSE;
+         staticp = false;
          switch (**pp)
            {
            case '*':
              /* virtual member function, followed by index.  The sign
                 bit is supposedly set to distinguish
-                pointers-to-methods from virtual function indicies.  */
+                pointers-to-methods from virtual function indices.  */
              ++*pp;
-             voffset = parse_number (pp, (bfd_boolean *) NULL);
+             voffset = parse_number (pp, (bool *) NULL, p_end);
              if (**pp != ';')
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
              ++*pp;
              voffset &= 0x7fffffff;
 
-             if (**pp == ';' || *pp == '\0')
+             if (**pp == ';' || **pp == '\0')
                {
                  /* Must be g++ version 1.  */
                  context = DEBUG_TYPE_NULL;
@@ -2676,7 +2832,8 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                  look_ahead_type = parse_stab_type (dhandle, info,
                                                     (const char *) NULL,
                                                     pp,
-                                                    (debug_type **) NULL);
+                                                    (debug_type **) NULL,
+                                                    p_end);
                  if (**pp == ':')
                    {
                      /* g++ version 1 overloaded methods.  */
@@ -2689,7 +2846,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                      if (**pp != ';')
                        {
                          bad_stab (orig);
-                         return FALSE;
+                         goto fail;
                        }
                      ++*pp;
                    }
@@ -2699,11 +2856,11 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
            case '?':
              /* static member function.  */
              ++*pp;
-             staticp = TRUE;
+             staticp = true;
              voffset = 0;
              context = DEBUG_TYPE_NULL;
              if (strncmp (argtypes, name, strlen (name)) != 0)
-               stub = TRUE;
+               stub = true;
              break;
 
            default:
@@ -2724,26 +2881,25 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
              argtypes string is the mangled form of the argument
              types, and the full type and the physical name must be
              extracted from them.  */
-         if (! stub)
-           physname = argtypes;
-         else
+         physname = argtypes;
+         if (stub)
            {
              debug_type class_type, return_type;
 
              class_type = stab_find_type (dhandle, info, typenums);
              if (class_type == DEBUG_TYPE_NULL)
-               return FALSE;
+               goto fail;
              return_type = debug_get_return_type (dhandle, type);
              if (return_type == DEBUG_TYPE_NULL)
                {
                  bad_stab (orig);
-                 return FALSE;
+                 goto fail;
                }
              type = parse_stab_argtypes (dhandle, info, class_type, name,
                                          tagname, return_type, argtypes,
                                          constp, volatilep, &physname);
              if (type == DEBUG_TYPE_NULL)
-               return FALSE;
+               goto fail;
            }
 
          if (cvars + 1 >= allocvars)
@@ -2767,7 +2923,7 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
                                                                constp,
                                                                volatilep);
          if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
-           return FALSE;
+           goto fail;
 
          ++cvars;
        }
@@ -2795,7 +2951,13 @@ parse_stab_members (void *dhandle, struct stab_handle *info,
 
   *retp = methods;
 
-  return TRUE;
+  return true;
+
+ fail:
+  free (name);
+  free (variants);
+  free (argtypes);
+  return false;
 }
 
 /* Parse a string representing argument types for a method.  Stabs
@@ -2808,14 +2970,15 @@ static debug_type
 parse_stab_argtypes (void *dhandle, struct stab_handle *info,
                     debug_type class_type, const char *fieldname,
                     const char *tagname, debug_type return_type,
-                    const char *argtypes, bfd_boolean constp,
-                    bfd_boolean volatilep, const char **pphysname)
+                    const char *argtypes, bool constp,
+                    bool volatilep, const char **pphysname)
 {
-  bfd_boolean is_full_physname_constructor;
-  bfd_boolean is_constructor;
-  bfd_boolean is_destructor;
+  bool is_full_physname_constructor;
+  bool is_constructor;
+  bool is_destructor;
+  bool is_v3;
   debug_type *args;
-  bfd_boolean varargs;
+  bool varargs;
   unsigned int physname_len = 0;
 
   /* Constructors are sometimes handled specially.  */
@@ -2824,7 +2987,7 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
                                   && (ISDIGIT (argtypes[2])
                                       || argtypes[2] == 'Q'
                                       || argtypes[2] == 't'))
-                                 || strncmp (argtypes, "__ct", 4) == 0);
+                                 || startswith (argtypes, "__ct"));
 
   is_constructor = (is_full_physname_constructor
                    || (tagname != NULL
@@ -2832,11 +2995,10 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
   is_destructor = ((argtypes[0] == '_'
                    && (argtypes[1] == '$' || argtypes[1] == '.')
                    && argtypes[2] == '_')
-                  || strncmp (argtypes, "__dt", 4) == 0);
+                  || startswith (argtypes, "__dt"));
+  is_v3 = argtypes[0] == '_' && argtypes[1] == 'Z';
 
-  if (is_destructor || is_full_physname_constructor)
-    *pphysname = argtypes;
-  else
+  if (!(is_destructor || is_full_physname_constructor || is_v3))
     {
       unsigned int len;
       const char *const_prefix;
@@ -2871,27 +3033,15 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
          && fieldname[1] == 'p'
          && (fieldname[2] == '$' || fieldname[2] == '.'))
        {
-         const char *opname;
-
-         opname = cplus_mangle_opname (fieldname + 3, 0);
-         if (opname == NULL)
-           {
-             fprintf (stderr, _("No mangling for \"%s\"\n"), fieldname);
-             return DEBUG_TYPE_NULL;
-           }
-         mangled_name_len += strlen (opname);
-         physname = (char *) xmalloc (mangled_name_len);
-         strncpy (physname, fieldname, 3);
-         strcpy (physname + 3, opname);
+         /* Opname selection is no longer supported by libiberty's demangler.  */
+         return DEBUG_TYPE_NULL;
        }
+
+      physname = (char *) xmalloc (mangled_name_len);
+      if (is_constructor)
+       physname[0] = '\0';
       else
-       {
-         physname = (char *) xmalloc (mangled_name_len);
-         if (is_constructor)
-           physname[0] = '\0';
-         else
-           strcpy (physname, fieldname);
-       }
+       strcpy (physname, fieldname);
 
       physname_len = strlen (physname);
       strcat (physname, buf);
@@ -2907,7 +3057,7 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
       args = (debug_type *) xmalloc (sizeof *args);
       *args = NULL;
       return debug_make_method_type (dhandle, return_type, class_type, args,
-                                    FALSE);
+                                    false);
     }
 
   args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs, physname_len);
@@ -2926,27 +3076,32 @@ parse_stab_argtypes (void *dhandle, struct stab_handle *info,
    This function is called when we have parsed all the method declarations,
    so we can look for the vptr base class info.  */
 
-static bfd_boolean
-parse_stab_tilde_field (void *dhandle, struct stab_handle *info,
-                       const char **pp, const int *typenums,
-                       debug_type *retvptrbase, bfd_boolean *retownvptr)
+static bool
+parse_stab_tilde_field (void *dhandle,
+                       struct stab_handle *info,
+                       const char **pp,
+                       const int *typenums,
+                       debug_type *retvptrbase,
+                       bool *retownvptr,
+                       const char *p_end)
 {
   const char *orig;
   const char *hold;
   int vtypenums[2];
 
   *retvptrbase = DEBUG_TYPE_NULL;
-  *retownvptr = FALSE;
+  *retownvptr = false;
 
   orig = *pp;
-
+  if (orig >= p_end)
+    return false;
+  
   /* If we are positioned at a ';', then skip it.  */
   if (**pp == ';')
     ++*pp;
 
   if (**pp != '~')
-    return TRUE;
-
+    return true;
   ++*pp;
 
   if (**pp == '=' || **pp == '+' || **pp == '-')
@@ -2957,20 +3112,19 @@ parse_stab_tilde_field (void *dhandle, struct stab_handle *info,
     }
 
   if (**pp != '%')
-    return TRUE;
-
+    return true;
   ++*pp;
 
   hold = *pp;
 
   /* The next number is the type number of the base class (possibly
      our own class) which supplies the vtable for this class.  */
-  if (! parse_stab_type_number (pp, vtypenums))
-    return FALSE;
+  if (! parse_stab_type_number (pp, vtypenums, p_end))
+    return false;
 
   if (vtypenums[0] == typenums[0]
       && vtypenums[1] == typenums[1])
-    *retownvptr = TRUE;
+    *retownvptr = true;
   else
     {
       debug_type vtype;
@@ -2979,13 +3133,13 @@ parse_stab_tilde_field (void *dhandle, struct stab_handle *info,
       *pp = hold;
 
       vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                              (debug_type **) NULL);
+                              (debug_type **) NULL, p_end);
       for (p = *pp; *p != ';' && *p != '\0'; p++)
        ;
       if (*p != ';')
        {
          bad_stab (orig);
-         return FALSE;
+         return false;
        }
 
       *retvptrbase = vtype;
@@ -2993,20 +3147,23 @@ parse_stab_tilde_field (void *dhandle, struct stab_handle *info,
       *pp = p + 1;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Read a definition of an array type.  */
 
 static debug_type
-parse_stab_array_type (void *dhandle, struct stab_handle *info,
-                      const char **pp, bfd_boolean stringp)
+parse_stab_array_type (void *dhandle,
+                      struct stab_handle *info,
+                      const char **pp,
+                      bool stringp,
+                      const char *p_end)
 {
   const char *orig;
   const char *p;
   int typenums[2];
   debug_type index_type;
-  bfd_boolean adjustable;
+  bool adjustable;
   bfd_signed_vma lower, upper;
   debug_type element_type;
 
@@ -3018,19 +3175,22 @@ parse_stab_array_type (void *dhandle, struct stab_handle *info,
      for these, produce a type like float[][].  */
 
   orig = *pp;
+  if (orig >= p_end)
+    return DEBUG_TYPE_NULL;
 
   /* FIXME: gdb checks os9k_stabs here.  */
 
   /* If the index type is type 0, we take it as int.  */
   p = *pp;
-  if (! parse_stab_type_number (&p, typenums))
+  if (! parse_stab_type_number (&p, typenums, p_end))
     return DEBUG_TYPE_NULL;
+
   if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
     {
       index_type = debug_find_named_type (dhandle, "int");
       if (index_type == DEBUG_TYPE_NULL)
        {
-         index_type = debug_make_int_type (dhandle, 4, FALSE);
+         index_type = debug_make_int_type (dhandle, 4, false);
          if (index_type == DEBUG_TYPE_NULL)
            return DEBUG_TYPE_NULL;
        }
@@ -3039,7 +3199,7 @@ parse_stab_array_type (void *dhandle, struct stab_handle *info,
   else
     {
       index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                   (debug_type **) NULL);
+                                   (debug_type **) NULL, p_end);
     }
 
   if (**pp != ';')
@@ -3049,15 +3209,15 @@ parse_stab_array_type (void *dhandle, struct stab_handle *info,
     }
   ++*pp;
 
-  adjustable = FALSE;
+  adjustable = false;
 
-  if (! ISDIGIT (**pp) && **pp != '-')
+  if (! ISDIGIT (**pp) && **pp != '-' && **pp != 0)
     {
       ++*pp;
-      adjustable = TRUE;
+      adjustable = true;
     }
 
-  lower = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
+  lower = (bfd_signed_vma) parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -3065,13 +3225,13 @@ parse_stab_array_type (void *dhandle, struct stab_handle *info,
     }
   ++*pp;
 
-  if (! ISDIGIT (**pp) && **pp != '-')
+  if (! ISDIGIT (**pp) && **pp != '-' && **pp != 0)
     {
       ++*pp;
-      adjustable = TRUE;
+      adjustable = true;
     }
 
-  upper = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
+  upper = (bfd_signed_vma) parse_number (pp, (bool *) NULL, p_end);
   if (**pp != ';')
     {
       bad_stab (orig);
@@ -3080,7 +3240,7 @@ parse_stab_array_type (void *dhandle, struct stab_handle *info,
   ++*pp;
 
   element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
-                                 (debug_type **) NULL);
+                                 (debug_type **) NULL, p_end);
   if (element_type == DEBUG_TYPE_NULL)
     return DEBUG_TYPE_NULL;
 
@@ -3151,6 +3311,9 @@ pop_bincl (struct stab_handle *info)
     return info->main_filename;
   info->bincl_stack = o->next_stack;
 
+  if (o->file >= info->files)
+    return info->main_filename;
+
   o->file_types = info->file_types[o->file];
 
   if (info->bincl_stack == NULL)
@@ -3160,7 +3323,7 @@ pop_bincl (struct stab_handle *info)
 
 /* Handle an N_EXCL: get the types from the corresponding N_BINCL.  */
 
-static bfd_boolean
+static bool
 find_excl (struct stab_handle *info, const char *name, bfd_vma hash)
 {
   struct bincl_file *l;
@@ -3178,12 +3341,12 @@ find_excl (struct stab_handle *info, const char *name, bfd_vma hash)
     {
       warn_stab (name, _("Undefined N_EXCL"));
       info->file_types[info->files - 1] = NULL;
-      return TRUE;
+      return true;
     }
 
   info->file_types[info->files - 1] = l->file_types;
 
-  return TRUE;
+  return true;
 }
 
 /* Handle a variable definition.  gcc emits variable definitions for a
@@ -3191,7 +3354,7 @@ find_excl (struct stab_handle *info, const char *name, bfd_vma hash)
    it.  The SunPRO compiler emits variable definitions after the
    N_LBRAC, so we can call debug_record_variable immediately.  */
 
-static bfd_boolean
+static bool
 stab_record_variable (void *dhandle, struct stab_handle *info,
                      const char *name, debug_type type,
                      enum debug_var_kind kind, bfd_vma val)
@@ -3213,13 +3376,13 @@ stab_record_variable (void *dhandle, struct stab_handle *info,
   v->val = val;
   info->pending = v;
 
-  return TRUE;
+  return true;
 }
 
 /* Emit pending variable definitions.  This is called after we see the
    N_LBRAC that starts the block.  */
 
-static bfd_boolean
+static bool
 stab_emit_pending_vars (void *dhandle, struct stab_handle *info)
 {
   struct stab_pending_var *v;
@@ -3230,7 +3393,7 @@ stab_emit_pending_vars (void *dhandle, struct stab_handle *info)
       struct stab_pending_var *next;
 
       if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
-       return FALSE;
+       return false;
 
       next = v->next;
       free (v);
@@ -3239,7 +3402,7 @@ stab_emit_pending_vars (void *dhandle, struct stab_handle *info)
 
   info->pending = NULL;
 
-  return TRUE;
+  return true;
 }
 
 /* Find the slot for a type in the database.  */
@@ -3248,26 +3411,26 @@ static debug_type *
 stab_find_slot (struct stab_handle *info, const int *typenums)
 {
   int filenum;
-  int index;
+  int tindex;
   struct stab_types **ps;
 
   filenum = typenums[0];
-  index = typenums[1];
+  tindex = typenums[1];
 
   if (filenum < 0 || (unsigned int) filenum >= info->files)
     {
       fprintf (stderr, _("Type file number %d out of range\n"), filenum);
       return NULL;
     }
-  if (index < 0)
+  if (tindex < 0)
     {
-      fprintf (stderr, _("Type index number %d out of range\n"), index);
+      fprintf (stderr, _("Type index number %d out of range\n"), tindex);
       return NULL;
     }
 
   ps = info->file_types + filenum;
 
-  while (index >= STAB_TYPES_SLOTS)
+  while (tindex >= STAB_TYPES_SLOTS)
     {
       if (*ps == NULL)
        {
@@ -3275,7 +3438,7 @@ stab_find_slot (struct stab_handle *info, const int *typenums)
          memset (*ps, 0, sizeof **ps);
        }
       ps = &(*ps)->next;
-      index -= STAB_TYPES_SLOTS;
+      tindex -= STAB_TYPES_SLOTS;
     }
   if (*ps == NULL)
     {
@@ -3283,7 +3446,7 @@ stab_find_slot (struct stab_handle *info, const int *typenums)
       memset (*ps, 0, sizeof **ps);
     }
 
-  return (*ps)->types + index;
+  return (*ps)->types + tindex;
 }
 
 /* Find a type given a type number.  If the type has not been
@@ -3312,7 +3475,7 @@ stab_find_type (void *dhandle, struct stab_handle *info, const int *typenums)
 
 /* Record that a given type number refers to a given type.  */
 
-static bfd_boolean
+static bool
 stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info,
                  const int *typenums, debug_type type)
 {
@@ -3320,13 +3483,13 @@ stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info,
 
   slot = stab_find_slot (info, typenums);
   if (slot == NULL)
-    return FALSE;
+    return false;
 
   /* gdb appears to ignore type redefinitions, so we do as well.  */
 
   *slot = type;
 
-  return TRUE;
+  return true;
 }
 
 /* Return an XCOFF builtin type.  */
@@ -3352,42 +3515,43 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
       /* The size of this and all the other types are fixed, defined
         by the debugging format.  */
       name = "int";
-      rettype = debug_make_int_type (dhandle, 4, FALSE);
+      rettype = debug_make_int_type (dhandle, 4, false);
       break;
     case 2:
       name = "char";
-      rettype = debug_make_int_type (dhandle, 1, FALSE);
+      rettype = debug_make_int_type (dhandle, 1, false);
       break;
     case 3:
       name = "short";
-      rettype = debug_make_int_type (dhandle, 2, FALSE);
+      rettype = debug_make_int_type (dhandle, 2, false);
       break;
     case 4:
       name = "long";
-      rettype = debug_make_int_type (dhandle, 4, FALSE);
+      rettype = debug_make_int_type (dhandle, 4, false);
       break;
     case 5:
       name = "unsigned char";
-      rettype = debug_make_int_type (dhandle, 1, TRUE);
+      rettype = debug_make_int_type (dhandle, 1, true);
       break;
     case 6:
       name = "signed char";
-      rettype = debug_make_int_type (dhandle, 1, FALSE);
+      rettype = debug_make_int_type (dhandle, 1, false);
       break;
     case 7:
       name = "unsigned short";
-      rettype = debug_make_int_type (dhandle, 2, TRUE);
+      rettype = debug_make_int_type (dhandle, 2, true);
       break;
     case 8:
       name = "unsigned int";
-      rettype = debug_make_int_type (dhandle, 4, TRUE);
+      rettype = debug_make_int_type (dhandle, 4, true);
       break;
     case 9:
       name = "unsigned";
-      rettype = debug_make_int_type (dhandle, 4, TRUE);
+      rettype = debug_make_int_type (dhandle, 4, true);
+      break;
     case 10:
       name = "unsigned long";
-      rettype = debug_make_int_type (dhandle, 4, TRUE);
+      rettype = debug_make_int_type (dhandle, 4, true);
       break;
     case 11:
       name = "void";
@@ -3412,7 +3576,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
       break;
     case 15:
       name = "integer";
-      rettype = debug_make_int_type (dhandle, 4, FALSE);
+      rettype = debug_make_int_type (dhandle, 4, false);
       break;
     case 16:
       name = "boolean";
@@ -3434,7 +3598,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
     case 20:
       /* FIXME */
       name = "character";
-      rettype = debug_make_int_type (dhandle, 1, TRUE);
+      rettype = debug_make_int_type (dhandle, 1, true);
       break;
     case 21:
       name = "logical*1";
@@ -3464,28 +3628,28 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
       break;
     case 27:
       name = "integer*1";
-      rettype = debug_make_int_type (dhandle, 1, FALSE);
+      rettype = debug_make_int_type (dhandle, 1, false);
       break;
     case 28:
       name = "integer*2";
-      rettype = debug_make_int_type (dhandle, 2, FALSE);
+      rettype = debug_make_int_type (dhandle, 2, false);
       break;
     case 29:
       name = "integer*4";
-      rettype = debug_make_int_type (dhandle, 4, FALSE);
+      rettype = debug_make_int_type (dhandle, 4, false);
       break;
     case 30:
       /* FIXME */
       name = "wchar";
-      rettype = debug_make_int_type (dhandle, 2, FALSE);
+      rettype = debug_make_int_type (dhandle, 2, false);
       break;
     case 31:
       name = "long long";
-      rettype = debug_make_int_type (dhandle, 8, FALSE);
+      rettype = debug_make_int_type (dhandle, 8, false);
       break;
     case 32:
       name = "unsigned long long";
-      rettype = debug_make_int_type (dhandle, 8, TRUE);
+      rettype = debug_make_int_type (dhandle, 8, true);
       break;
     case 33:
       name = "logical*8";
@@ -3493,7 +3657,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
       break;
     case 34:
       name = "integer*8";
-      rettype = debug_make_int_type (dhandle, 8, FALSE);
+      rettype = debug_make_int_type (dhandle, 8, false);
       break;
     default:
       abort ();
@@ -3591,7 +3755,7 @@ struct stab_demangle_info
   /* The array of arguments we are building.  */
   debug_type *args;
   /* Whether the method takes a variable number of arguments.  */
-  bfd_boolean varargs;
+  bool varargs;
   /* The array of types we have remembered.  */
   struct stab_demangle_typestring *typestrings;
   /* The number of typestrings.  */
@@ -3602,29 +3766,29 @@ struct stab_demangle_info
 
 static void stab_bad_demangle (const char *);
 static unsigned int stab_demangle_count (const char **);
-static bfd_boolean stab_demangle_get_count (const char **, unsigned int *);
-static bfd_boolean stab_demangle_prefix
+static bool stab_demangle_get_count (const char **, unsigned int *);
+static bool stab_demangle_prefix
   (struct stab_demangle_info *, const char **, unsigned int);
-static bfd_boolean stab_demangle_function_name
+static bool stab_demangle_function_name
   (struct stab_demangle_info *, const char **, const char *);
-static bfd_boolean stab_demangle_signature
+static bool stab_demangle_signature
   (struct stab_demangle_info *, const char **);
-static bfd_boolean stab_demangle_qualified
+static bool stab_demangle_qualified
   (struct stab_demangle_info *, const char **, debug_type *);
-static bfd_boolean stab_demangle_template
+static bool stab_demangle_template
   (struct stab_demangle_info *, const char **, char **);
-static bfd_boolean stab_demangle_class
+static bool stab_demangle_class
   (struct stab_demangle_info *, const char **, const char **);
-static bfd_boolean stab_demangle_args
-  (struct stab_demangle_info *, const char **, debug_type **, bfd_boolean *);
-static bfd_boolean stab_demangle_arg
+static bool stab_demangle_args
+  (struct stab_demangle_info *, const char **, debug_type **, bool *);
+static bool stab_demangle_arg
   (struct stab_demangle_info *, const char **, debug_type **,
    unsigned int *, unsigned int *);
-static bfd_boolean stab_demangle_type
+static bool stab_demangle_type
   (struct stab_demangle_info *, const char **, debug_type *);
-static bfd_boolean stab_demangle_fund_type
+static bool stab_demangle_fund_type
   (struct stab_demangle_info *, const char **, debug_type *);
-static bfd_boolean stab_demangle_remember_type
+static bool stab_demangle_remember_type
   (struct stab_demangle_info *, const char *, int);
 
 /* Warn about a bad demangling.  */
@@ -3655,11 +3819,11 @@ stab_demangle_count (const char **pp)
 /* Require a count in a string.  The count may be multiple digits, in
    which case it must end in an underscore.  */
 
-static bfd_boolean
+static bool
 stab_demangle_get_count (const char **pp, unsigned int *pi)
 {
   if (! ISDIGIT (**pp))
-    return FALSE;
+    return false;
 
   *pi = **pp - '0';
   ++*pp;
@@ -3684,7 +3848,7 @@ stab_demangle_get_count (const char **pp, unsigned int *pi)
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* This function demangles a physical name, returning a NULL
@@ -3692,15 +3856,19 @@ stab_demangle_get_count (const char **pp, unsigned int *pi)
 
 static debug_type *
 stab_demangle_argtypes (void *dhandle, struct stab_handle *info,
-                       const char *physname, bfd_boolean *pvarargs,
+                       const char *physname, bool *pvarargs,
                        unsigned int physname_len)
 {
   struct stab_demangle_info minfo;
 
+  /* Check for the g++ V3 ABI.  */
+  if (physname[0] == '_' && physname[1] == 'Z')
+    return stab_demangle_v3_argtypes (dhandle, info, physname, pvarargs);
+
   minfo.dhandle = dhandle;
   minfo.info = info;
   minfo.args = NULL;
-  minfo.varargs = FALSE;
+  minfo.varargs = false;
   minfo.typestring_alloc = 10;
   minfo.typestrings = ((struct stab_demangle_typestring *)
                       xmalloc (minfo.typestring_alloc
@@ -3729,14 +3897,13 @@ stab_demangle_argtypes (void *dhandle, struct stab_handle *info,
   return minfo.args;
 
  error_return:
-  if (minfo.typestrings != NULL)
-    free (minfo.typestrings);
+  free (minfo.typestrings);
   return NULL;
 }
 
 /* Demangle the prefix of the mangled name.  */
 
-static bfd_boolean
+static bool
 stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
                      unsigned int physname_len)
 {
@@ -3759,7 +3926,7 @@ stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
       if (scan == NULL)
        {
          stab_bad_demangle (*pp);
-         return FALSE;
+         return false;
        }
 
       --scan;
@@ -3777,7 +3944,7 @@ stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
     {
       /* This is a GNU style constructor name.  */
       *pp = scan + 2;
-      return TRUE;
+      return true;
     }
   else if (scan == *pp
           && ! ISDIGIT (scan[2])
@@ -3791,7 +3958,7 @@ stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
       if (scan == NULL || scan[2] == '\0')
        {
          stab_bad_demangle (*pp);
-         return FALSE;
+         return false;
        }
 
       return stab_demangle_function_name (minfo, pp, scan);
@@ -3804,7 +3971,7 @@ stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
   else
     {
       stab_bad_demangle (*pp);
-      return FALSE;
+      return false;
     }
   /*NOTREACHED*/
 }
@@ -3813,7 +3980,7 @@ stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp,
    double underscore which separates the function name from the
    signature.  */
 
-static bfd_boolean
+static bool
 stab_demangle_function_name (struct stab_demangle_info *minfo,
                             const char **pp, const char *scan)
 {
@@ -3828,7 +3995,7 @@ stab_demangle_function_name (struct stab_demangle_info *minfo,
   *pp = scan + 2;
 
   if (*pp - name >= 5
-          && strncmp (name, "type", 4) == 0
+          && startswith (name, "type")
           && (name[4] == '$' || name[4] == '.'))
     {
       const char *tem;
@@ -3836,7 +4003,7 @@ stab_demangle_function_name (struct stab_demangle_info *minfo,
       /* This is a type conversion operator.  */
       tem = name + 5;
       if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
-       return FALSE;
+       return false;
     }
   else if (name[0] == '_'
           && name[1] == '_'
@@ -3848,26 +4015,26 @@ stab_demangle_function_name (struct stab_demangle_info *minfo,
       /* This is a type conversion operator.  */
       tem = name + 4;
       if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
-       return FALSE;
+       return false;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle the signature.  This is where the argument types are
    found.  */
 
-static bfd_boolean
+static bool
 stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
 {
   const char *orig;
-  bfd_boolean expect_func, func_done;
+  bool expect_func, func_done;
   const char *hold;
 
   orig = *pp;
 
-  expect_func = FALSE;
-  func_done = FALSE;
+  expect_func = false;
+  func_done = false;
   hold = NULL;
 
   while (**pp != '\0')
@@ -3878,8 +4045,8 @@ stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
          hold = *pp;
          if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
              || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
-           return FALSE;
-         expect_func = TRUE;
+           return false;
+         expect_func = true;
          hold = NULL;
          break;
 
@@ -3903,8 +4070,8 @@ stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
            hold = *pp;
          if (! stab_demangle_class (minfo, pp, (const char **) NULL)
              || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
-           return FALSE;
-         expect_func = TRUE;
+           return false;
+         expect_func = true;
          hold = NULL;
          break;
 
@@ -3912,10 +4079,10 @@ stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
          /* Function.  I don't know if this actually happens with g++
              output.  */
          hold = NULL;
-         func_done = TRUE;
+         func_done = true;
          ++*pp;
          if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
-           return FALSE;
+           return false;
          break;
 
        case 't':
@@ -3924,9 +4091,9 @@ stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
            hold = *pp;
          if (! stab_demangle_template (minfo, pp, (char **) NULL)
              || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
-           return FALSE;
+           return false;
          hold = NULL;
-         expect_func = TRUE;
+         expect_func = true;
          break;
 
        case '_':
@@ -3936,22 +4103,22 @@ stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
             has been mangled by some algorithm we don't know how to
             deal with.  So just reject the entire demangling.  */
          stab_bad_demangle (orig);
-         return FALSE;
+         return false;
 
        default:
          /* Assume we have stumbled onto the first outermost function
             argument token, and start processing args.  */
-         func_done = TRUE;
+         func_done = true;
          if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
-           return FALSE;
+           return false;
          break;
        }
 
       if (expect_func)
        {
-         func_done = TRUE;
+         func_done = true;
          if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
-           return FALSE;
+           return false;
        }
     }
 
@@ -3962,16 +4129,16 @@ stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
         first case, and need to ensure that the '(void)' gets added
         to the current declp.  */
       if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
-       return FALSE;
+       return false;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle a qualified name, such as "Q25Outer5Inner" which is the
    mangled form of "Outer::Inner".  */
 
-static bfd_boolean
+static bool
 stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
                         debug_type *ptype)
 {
@@ -3992,7 +4159,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
       if (! ISDIGIT (*p) || *p == '0')
        {
          stab_bad_demangle (orig);
-         return FALSE;
+         return false;
        }
       qualifiers = atoi (p);
       while (ISDIGIT (*p))
@@ -4000,7 +4167,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
       if (*p != '_')
        {
          stab_bad_demangle (orig);
-         return FALSE;
+         return false;
        }
       *pp = p + 1;
       break;
@@ -4017,7 +4184,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
     case '0':
     default:
       stab_bad_demangle (orig);
-      return FALSE;
+      return false;
     }
 
   context = DEBUG_TYPE_NULL;
@@ -4033,7 +4200,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
 
          if (! stab_demangle_template (minfo, pp,
                                        ptype != NULL ? &name : NULL))
-           return FALSE;
+           return false;
 
          if (ptype != NULL)
            {
@@ -4042,7 +4209,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
                                               DEBUG_KIND_CLASS);
              free (name);
              if (context == DEBUG_TYPE_NULL)
-               return FALSE;
+               return false;
            }
        }
       else
@@ -4053,7 +4220,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
          if (strlen (*pp) < len)
            {
              stab_bad_demangle (orig);
-             return FALSE;
+             return false;
            }
 
          if (ptype != NULL)
@@ -4087,7 +4254,10 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
 
                      ft = debug_get_field_type (minfo->dhandle, *fields);
                      if (ft == NULL)
-                       return FALSE;
+                       {
+                         free (name);
+                         return false;
+                       }
                      dn = debug_get_type_name (minfo->dhandle, ft);
                      if (dn != NULL && strcmp (dn, name) == 0)
                        {
@@ -4124,7 +4294,7 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
                                                        ? DEBUG_KIND_ILLEGAL
                                                        : DEBUG_KIND_CLASS));
                      if (context == DEBUG_TYPE_NULL)
-                       return FALSE;
+                       return false;
                    }
                }
            }
@@ -4136,13 +4306,13 @@ stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp,
   if (ptype != NULL)
     *ptype = context;
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle a template.  If PNAME is not NULL, this sets *PNAME to a
    string representation of the template.  */
 
-static bfd_boolean
+static bool
 stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
                        char **pname)
 {
@@ -4158,7 +4328,7 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
   if (r == 0 || strlen (*pp) < r)
     {
       stab_bad_demangle (orig);
-      return FALSE;
+      return false;
     }
   *pp += r;
 
@@ -4166,7 +4336,7 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
   if (stab_demangle_get_count (pp, &r) == 0)
     {
       stab_bad_demangle (orig);
-      return FALSE;
+      return false;
     }
 
   for (i = 0; i < r; i++)
@@ -4176,26 +4346,26 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
          /* This is a type parameter.  */
          ++*pp;
          if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
-           return FALSE;
+           return false;
        }
       else
        {
          const char *old_p;
-         bfd_boolean pointerp, realp, integralp, charp, boolp;
-         bfd_boolean done;
+         bool pointerp, realp, integralp, charp, boolp;
+         bool done;
 
          old_p = *pp;
-         pointerp = FALSE;
-         realp = FALSE;
-         integralp = FALSE;
-         charp = FALSE;
-         boolp = FALSE;
-         done = FALSE;
+         pointerp = false;
+         realp = false;
+         integralp = false;
+         charp = false;
+         boolp = false;
+         done = false;
 
          /* This is a value parameter.  */
 
          if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
-           return FALSE;
+           return false;
 
          while (*old_p != '\0' && ! done)
            {
@@ -4204,8 +4374,8 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
                case 'P':
                case 'p':
                case 'R':
-                 pointerp = TRUE;
-                 done = TRUE;
+                 pointerp = true;
+                 done = true;
                  break;
                case 'C':       /* Const.  */
                case 'S':       /* Signed.  */
@@ -4217,8 +4387,8 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
                  ++old_p;
                  break;
                case 'Q':       /* Qualified name.  */
-                 integralp = TRUE;
-                 done = TRUE;
+                 integralp = true;
+                 done = true;
                  break;
                case 'T':       /* Remembered type.  */
                  abort ();
@@ -4229,27 +4399,27 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
                case 'i':       /* Int.  */
                case 's':       /* Short.  */
                case 'w':       /* Wchar_t.  */
-                 integralp = TRUE;
-                 done = TRUE;
+                 integralp = true;
+                 done = true;
                  break;
                case 'b':       /* Bool.  */
-                 boolp = TRUE;
-                 done = TRUE;
+                 boolp = true;
+                 done = true;
                  break;
                case 'c':       /* Char.  */
-                 charp = TRUE;
-                 done = TRUE;
+                 charp = true;
+                 done = true;
                  break;
                case 'r':       /* Long double.  */
                case 'd':       /* Double.  */
                case 'f':       /* Float.  */
-                 realp = TRUE;
-                 done = TRUE;
+                 realp = true;
+                 done = true;
                  break;
                default:
                  /* Assume it's a user defined integral type.  */
-                 integralp = TRUE;
-                 done = TRUE;
+                 integralp = true;
+                 done = true;
                  break;
                }
            }
@@ -4271,7 +4441,7 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
              if (val == 0)
                {
                  stab_bad_demangle (orig);
-                 return FALSE;
+                 return false;
                }
            }
          else if (boolp)
@@ -4282,7 +4452,7 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
              if (val != 0 && val != 1)
                {
                  stab_bad_demangle (orig);
-                 return FALSE;
+                 return false;
                }
            }
          else if (realp)
@@ -4308,10 +4478,11 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
            {
              unsigned int len;
 
-             if (! stab_demangle_get_count (pp, &len))
+             len = stab_demangle_count (pp);
+             if (len == 0)
                {
                  stab_bad_demangle (orig);
-                 return FALSE;
+                 return false;
                }
              *pp += len;
            }
@@ -4331,7 +4502,7 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
 
       free (s1);
 
-      s3 = cplus_demangle (s2, DMGL_ANSI);
+      s3 = cplus_demangle (s2, demangle_flags);
 
       free (s2);
 
@@ -4340,9 +4511,8 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
       if (s3 == NULL || s4 == NULL)
        {
          stab_bad_demangle (orig);
-         if (s3 != NULL)
-           free (s3);
-         return FALSE;
+         free (s3);
+         return false;
        }
 
       /* Eliminating all spaces, except those between > characters,
@@ -4358,12 +4528,12 @@ stab_demangle_template (struct stab_demangle_info *minfo, const char **pp,
       free (s3);
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle a class name.  */
 
-static bfd_boolean
+static bool
 stab_demangle_class (struct stab_demangle_info *minfo ATTRIBUTE_UNUSED,
                     const char **pp, const char **pstart)
 {
@@ -4376,7 +4546,7 @@ stab_demangle_class (struct stab_demangle_info *minfo ATTRIBUTE_UNUSED,
   if (strlen (*pp) < n)
     {
       stab_bad_demangle (orig);
-      return FALSE;
+      return false;
     }
 
   if (pstart != NULL)
@@ -4384,15 +4554,15 @@ stab_demangle_class (struct stab_demangle_info *minfo ATTRIBUTE_UNUSED,
 
   *pp += n;
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle function arguments.  If the pargs argument is not NULL, it
    is set to a NULL terminated array holding the arguments.  */
 
-static bfd_boolean
+static bool
 stab_demangle_args (struct stab_demangle_info *minfo, const char **pp,
-                   debug_type **pargs, bfd_boolean *pvarargs)
+                   debug_type **pargs, bool *pvarargs)
 {
   const char *orig;
   unsigned int alloc, count;
@@ -4403,7 +4573,7 @@ stab_demangle_args (struct stab_demangle_info *minfo, const char **pp,
   if (pargs != NULL)
     {
       *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
-      *pvarargs = FALSE;
+      *pvarargs = false;
     }
   count = 0;
 
@@ -4424,20 +4594,20 @@ stab_demangle_args (struct stab_demangle_info *minfo, const char **pp,
              if (! stab_demangle_get_count (pp, &r))
                {
                  stab_bad_demangle (orig);
-                 return FALSE;
+                 return false;
                }
            }
 
          if (! stab_demangle_get_count (pp, &t))
            {
              stab_bad_demangle (orig);
-             return FALSE;
+             return false;
            }
 
          if (t >= minfo->typestring_count)
            {
              stab_bad_demangle (orig);
-             return FALSE;
+             return false;
            }
          while (r-- > 0)
            {
@@ -4445,13 +4615,13 @@ stab_demangle_args (struct stab_demangle_info *minfo, const char **pp,
 
              tem = minfo->typestrings[t].typestring;
              if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
-               return FALSE;
+               return false;
            }
        }
       else
        {
          if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
-           return FALSE;
+           return false;
        }
     }
 
@@ -4461,16 +4631,16 @@ stab_demangle_args (struct stab_demangle_info *minfo, const char **pp,
   if (**pp == 'e')
     {
       if (pargs != NULL)
-       *pvarargs = TRUE;
+       *pvarargs = true;
       ++*pp;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle a single argument.  */
 
-static bfd_boolean
+static bool
 stab_demangle_arg (struct stab_demangle_info *minfo, const char **pp,
                   debug_type **pargs, unsigned int *pcount,
                   unsigned int *palloc)
@@ -4482,12 +4652,12 @@ stab_demangle_arg (struct stab_demangle_info *minfo, const char **pp,
   if (! stab_demangle_type (minfo, pp,
                            pargs == NULL ? (debug_type *) NULL : &type)
       || ! stab_demangle_remember_type (minfo, start, *pp - start))
-    return FALSE;
+    return false;
 
   if (pargs != NULL)
     {
       if (type == DEBUG_TYPE_NULL)
-       return FALSE;
+       return false;
 
       if (*pcount + 1 >= *palloc)
        {
@@ -4499,13 +4669,13 @@ stab_demangle_arg (struct stab_demangle_info *minfo, const char **pp,
       ++*pcount;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle a type.  If the ptype argument is not NULL, *ptype is set
    to the newly allocated type.  */
 
-static bfd_boolean
+static bool
 stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
                    debug_type *ptype)
 {
@@ -4520,7 +4690,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
       /* A pointer type.  */
       ++*pp;
       if (! stab_demangle_type (minfo, pp, ptype))
-       return FALSE;
+       return false;
       if (ptype != NULL)
        *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
       break;
@@ -4529,7 +4699,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
       /* A reference type.  */
       ++*pp;
       if (! stab_demangle_type (minfo, pp, ptype))
-       return FALSE;
+       return false;
       if (ptype != NULL)
        *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
       break;
@@ -4546,7 +4716,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
            if (! ISDIGIT (**pp))
              {
                stab_bad_demangle (orig);
-               return FALSE;
+               return false;
              }
            high *= 10;
            high += **pp - '0';
@@ -4555,21 +4725,21 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
        if (**pp != '_')
          {
            stab_bad_demangle (orig);
-           return FALSE;
+           return false;
          }
        ++*pp;
 
        if (! stab_demangle_type (minfo, pp, ptype))
-         return FALSE;
+         return false;
        if (ptype != NULL)
          {
            debug_type int_type;
 
            int_type = debug_find_named_type (minfo->dhandle, "int");
            if (int_type == NULL)
-             int_type = debug_make_int_type (minfo->dhandle, 4, FALSE);
+             int_type = debug_make_int_type (minfo->dhandle, 4, false);
            *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
-                                           0, high, FALSE);
+                                           0, high, false);
          }
       }
       break;
@@ -4584,16 +4754,16 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
        if (! stab_demangle_get_count (pp, &i))
          {
            stab_bad_demangle (orig);
-           return FALSE;
+           return false;
          }
        if (i >= minfo->typestring_count)
          {
            stab_bad_demangle (orig);
-           return FALSE;
+           return false;
          }
        p = minfo->typestrings[i].typestring;
        if (! stab_demangle_type (minfo, &p, ptype))
-         return FALSE;
+         return false;
       }
       break;
 
@@ -4601,7 +4771,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
       /* A function.  */
       {
        debug_type *args;
-       bfd_boolean varargs;
+       bool varargs;
 
        ++*pp;
        if (! stab_demangle_args (minfo, pp,
@@ -4609,20 +4779,20 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
                                   ? (debug_type **) NULL
                                   : &args),
                                  (ptype == NULL
-                                  ? (bfd_boolean *) NULL
+                                  ? (bool *) NULL
                                   : &varargs)))
-         return FALSE;
+         return false;
        if (**pp != '_')
          {
            /* cplus_demangle will accept a function without a return
               type, but I don't know when that will happen, or what
               to do if it does.  */
            stab_bad_demangle (orig);
-           return FALSE;
+           return false;
          }
        ++*pp;
        if (! stab_demangle_type (minfo, pp, ptype))
-         return FALSE;
+         return false;
        if (ptype != NULL)
          *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
                                             varargs);
@@ -4633,18 +4803,16 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
     case 'M':
     case 'O':
       {
-       bfd_boolean memberp, constp, volatilep;
+       bool memberp;
        debug_type class_type = DEBUG_TYPE_NULL;
        debug_type *args;
-       bfd_boolean varargs;
+       bool varargs;
        unsigned int n;
        const char *name;
 
        memberp = **pp == 'M';
-       constp = FALSE;
-       volatilep = FALSE;
        args = NULL;
-       varargs = FALSE;
+       varargs = false;
 
        ++*pp;
        if (ISDIGIT (**pp))
@@ -4653,7 +4821,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
            if (strlen (*pp) < n)
              {
                stab_bad_demangle (orig);
-               return FALSE;
+               return false;
              }
            name = *pp;
            *pp += n;
@@ -4665,7 +4833,7 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
                                                    name, (int) n,
                                                    DEBUG_KIND_CLASS);
                if (class_type == DEBUG_TYPE_NULL)
-                 return FALSE;
+                 return false;
              }
          }
        else if (**pp == 'Q')
@@ -4674,30 +4842,28 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
                                           (ptype == NULL
                                            ? (debug_type *) NULL
                                            : &class_type)))
-             return FALSE;
+             return false;
          }
        else
          {
            stab_bad_demangle (orig);
-           return FALSE;
+           return false;
          }
 
        if (memberp)
          {
            if (**pp == 'C')
              {
-               constp = TRUE;
                ++*pp;
              }
            else if (**pp == 'V')
              {
-               volatilep = TRUE;
                ++*pp;
              }
            if (**pp != 'F')
              {
                stab_bad_demangle (orig);
-               return FALSE;
+               return false;
              }
            ++*pp;
            if (! stab_demangle_args (minfo, pp,
@@ -4705,20 +4871,20 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
                                       ? (debug_type **) NULL
                                       : &args),
                                      (ptype == NULL
-                                      ? (bfd_boolean *) NULL
+                                      ? (bool *) NULL
                                       : &varargs)))
-             return FALSE;
+             return false;
          }
 
        if (**pp != '_')
          {
            stab_bad_demangle (orig);
-           return FALSE;
+           return false;
          }
        ++*pp;
 
        if (! stab_demangle_type (minfo, pp, ptype))
-         return FALSE;
+         return false;
 
        if (ptype != NULL)
          {
@@ -4739,81 +4905,78 @@ stab_demangle_type (struct stab_demangle_info *minfo, const char **pp,
     case 'G':
       ++*pp;
       if (! stab_demangle_type (minfo, pp, ptype))
-       return FALSE;
+       return false;
       break;
 
     case 'C':
       ++*pp;
       if (! stab_demangle_type (minfo, pp, ptype))
-       return FALSE;
+       return false;
       if (ptype != NULL)
        *ptype = debug_make_const_type (minfo->dhandle, *ptype);
       break;
 
     case 'Q':
       {
-       const char *hold;
-
-       hold = *pp;
        if (! stab_demangle_qualified (minfo, pp, ptype))
-         return FALSE;
+         return false;
       }
       break;
 
     default:
       if (! stab_demangle_fund_type (minfo, pp, ptype))
-       return FALSE;
+       return false;
       break;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Demangle a fundamental type.  If the ptype argument is not NULL,
    *ptype is set to the newly allocated type.  */
 
-static bfd_boolean
+static bool
 stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
                         debug_type *ptype)
 {
   const char *orig;
-  bfd_boolean constp, volatilep, unsignedp, signedp;
-  bfd_boolean done;
+  bool constp, volatilep, unsignedp, signedp;
+  bool done;
 
   orig = *pp;
 
-  constp = FALSE;
-  volatilep = FALSE;
-  unsignedp = FALSE;
-  signedp = FALSE;
+  constp = false;
+  volatilep = false;
+  unsignedp = false;
+  signedp = false;
 
-  done = FALSE;
+  done = false;
   while (! done)
     {
       switch (**pp)
        {
        case 'C':
-         constp = TRUE;
+         constp = true;
          ++*pp;
          break;
 
        case 'U':
-         unsignedp = TRUE;
+         unsignedp = true;
          ++*pp;
          break;
 
        case 'S':
-         signedp = TRUE;
+         signedp = true;
          ++*pp;
          break;
 
        case 'V':
-         volatilep = TRUE;
+         volatilep = true;
          ++*pp;
          break;
 
        default:
-         done = TRUE;
+         done = true;
          break;
        }
     }
@@ -4918,7 +5081,7 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
        {
          *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
          if (*ptype == DEBUG_TYPE_NULL)
-           *ptype = debug_make_int_type (minfo->dhandle, 2, TRUE);
+           *ptype = debug_make_int_type (minfo->dhandle, 2, true);
        }
       ++*pp;
       break;
@@ -4958,7 +5121,7 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
       if (! ISDIGIT (**pp))
        {
          stab_bad_demangle (orig);
-         return FALSE;
+         return false;
        }
       /* Fall through.  */
     case '0': case '1': case '2': case '3': case '4':
@@ -4967,7 +5130,7 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
        const char *hold;
 
        if (! stab_demangle_class (minfo, pp, &hold))
-         return FALSE;
+         return false;
        if (ptype != NULL)
          {
            char *name;
@@ -4983,7 +5146,7 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
                                                hold, *pp - hold,
                                                DEBUG_KIND_ILLEGAL);
                if (*ptype == DEBUG_TYPE_NULL)
-                 return FALSE;
+                 return false;
              }
          }
       }
@@ -4995,7 +5158,7 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
 
        if (! stab_demangle_template (minfo, pp,
                                      ptype != NULL ? &name : NULL))
-         return FALSE;
+         return false;
        if (ptype != NULL)
          {
            *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
@@ -5003,14 +5166,14 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
                                            DEBUG_KIND_CLASS);
            free (name);
            if (*ptype == DEBUG_TYPE_NULL)
-             return FALSE;
+             return false;
          }
       }
       break;
 
     default:
       stab_bad_demangle (orig);
-      return FALSE;
+      return false;
     }
 
   if (ptype != NULL)
@@ -5021,12 +5184,12 @@ stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp,
        *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Remember a type string in a demangled string.  */
 
-static bfd_boolean
+static bool
 stab_demangle_remember_type (struct stab_demangle_info *minfo,
                             const char *p, int len)
 {
@@ -5043,5 +5206,348 @@ stab_demangle_remember_type (struct stab_demangle_info *minfo,
   minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
   ++minfo->typestring_count;
 
-  return TRUE;
+  return true;
+}
+\f
+/* Demangle names encoded using the g++ V3 ABI.  The newer versions of
+   g++ which use this ABI do not encode ordinary method argument types
+   in a mangled name; they simply output the argument types.  However,
+   for a static method, g++ simply outputs the return type and the
+   physical name.  So in that case we need to demangle the name here.
+   Here PHYSNAME is the physical name of the function, and we set the
+   variable pointed at by PVARARGS to indicate whether this function
+   is varargs.  This returns NULL, or a NULL terminated array of
+   argument types.  */
+
+static debug_type *
+stab_demangle_v3_argtypes (void *dhandle, struct stab_handle *info,
+                          const char *physname, bool *pvarargs)
+{
+  struct demangle_component *dc;
+  void *mem;
+  debug_type *pargs;
+
+  dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | demangle_flags, &mem);
+  if (dc == NULL)
+    {
+      stab_bad_demangle (physname);
+      return NULL;
+    }
+
+  /* We expect to see TYPED_NAME, and the right subtree describes the
+     function type.  */
+  if (dc->type != DEMANGLE_COMPONENT_TYPED_NAME
+      || dc->u.s_binary.right->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
+    {
+      fprintf (stderr, _("Demangled name is not a function\n"));
+      free (mem);
+      return NULL;
+    }
+
+  pargs = stab_demangle_v3_arglist (dhandle, info,
+                                   dc->u.s_binary.right->u.s_binary.right,
+                                   pvarargs);
+
+  free (mem);
+
+  return pargs;
+}
+
+/* Demangle an argument list in a struct demangle_component tree.
+   Returns a DEBUG_TYPE_NULL terminated array of argument types, and
+   sets *PVARARGS to indicate whether this is a varargs function.  */
+
+static debug_type *
+stab_demangle_v3_arglist (void *dhandle, struct stab_handle *info,
+                         struct demangle_component *arglist,
+                         bool *pvarargs)
+{
+  struct demangle_component *dc;
+  unsigned int alloc, count;
+  debug_type *pargs;
+
+  alloc = 10;
+  pargs = (debug_type *) xmalloc (alloc * sizeof *pargs);
+  *pvarargs = false;
+
+  count = 0;
+
+  for (dc = arglist;
+       dc != NULL;
+       dc = dc->u.s_binary.right)
+    {
+      debug_type arg;
+      bool varargs;
+
+      if (dc->type != DEMANGLE_COMPONENT_ARGLIST)
+       {
+         fprintf (stderr, _("Unexpected type in v3 arglist demangling\n"));
+         free (pargs);
+         return NULL;
+       }
+
+      /* PR 13925: Cope if the demangler returns an empty
+        context for a function with no arguments.  */
+      if (dc->u.s_binary.left == NULL)
+       break;
+
+      arg = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
+                                 NULL, &varargs);
+      if (arg == NULL)
+       {
+         if (varargs)
+           {
+             *pvarargs = true;
+             continue;
+           }
+         free (pargs);
+         return NULL;
+       }
+
+      if (count + 1 >= alloc)
+       {
+         alloc += 10;
+         pargs = (debug_type *) xrealloc (pargs, alloc * sizeof *pargs);
+       }
+
+      pargs[count] = arg;
+      ++count;
+    }
+
+  pargs[count] = DEBUG_TYPE_NULL;
+
+  return pargs;
+}
+
+/* Convert a struct demangle_component tree describing an argument
+   type into a debug_type.  */
+
+static debug_type
+stab_demangle_v3_arg (void *dhandle, struct stab_handle *info,
+                     struct demangle_component *dc, debug_type context,
+                     bool *pvarargs)
+{
+  debug_type dt;
+
+  if (pvarargs != NULL)
+    *pvarargs = false;
+
+  switch (dc->type)
+    {
+      /* FIXME: These are demangle component types which we probably
+        need to handle one way or another.  */
+    case DEMANGLE_COMPONENT_LOCAL_NAME:
+    case DEMANGLE_COMPONENT_TYPED_NAME:
+    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+    case DEMANGLE_COMPONENT_CTOR:
+    case DEMANGLE_COMPONENT_DTOR:
+    case DEMANGLE_COMPONENT_JAVA_CLASS:
+    case DEMANGLE_COMPONENT_RESTRICT_THIS:
+    case DEMANGLE_COMPONENT_VOLATILE_THIS:
+    case DEMANGLE_COMPONENT_CONST_THIS:
+    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+    case DEMANGLE_COMPONENT_COMPLEX:
+    case DEMANGLE_COMPONENT_IMAGINARY:
+    case DEMANGLE_COMPONENT_VENDOR_TYPE:
+    case DEMANGLE_COMPONENT_ARRAY_TYPE:
+    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+    case DEMANGLE_COMPONENT_ARGLIST:
+    default:
+      fprintf (stderr, _("Unrecognized demangle component %d\n"),
+              (int) dc->type);
+      return NULL;
+
+    case DEMANGLE_COMPONENT_NAME:
+      if (context != NULL)
+       {
+         const debug_field *fields;
+
+         fields = debug_get_fields (dhandle, context);
+         if (fields != NULL)
+           {
+             /* Try to find this type by looking through the context
+                class.  */
+             for (; *fields != DEBUG_FIELD_NULL; fields++)
+               {
+                 debug_type ft;
+                 const char *dn;
+
+                 ft = debug_get_field_type (dhandle, *fields);
+                 if (ft == NULL)
+                   return NULL;
+                 dn = debug_get_type_name (dhandle, ft);
+                 if (dn != NULL
+                     && (int) strlen (dn) == dc->u.s_name.len
+                     && strncmp (dn, dc->u.s_name.s, dc->u.s_name.len) == 0)
+                   return ft;
+               }
+           }
+       }
+      return stab_find_tagged_type (dhandle, info, dc->u.s_name.s,
+                                   dc->u.s_name.len, DEBUG_KIND_ILLEGAL);
+
+    case DEMANGLE_COMPONENT_QUAL_NAME:
+      context = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
+                                     context, NULL);
+      if (context == NULL)
+       return NULL;
+      return stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.right,
+                                  context, NULL);
+
+    case DEMANGLE_COMPONENT_TEMPLATE:
+      {
+       char *p;
+       size_t alc;
+
+       /* We print this component to get a class name which we can
+          use.  FIXME: This probably won't work if the template uses
+          template parameters which refer to an outer template.  */
+       p = cplus_demangle_print (DMGL_PARAMS | demangle_flags, dc, 20, &alc);
+       if (p == NULL)
+         {
+           fprintf (stderr, _("Failed to print demangled template\n"));
+           return NULL;
+         }
+       dt = stab_find_tagged_type (dhandle, info, p, strlen (p),
+                                   DEBUG_KIND_CLASS);
+       free (p);
+       return dt;
+      }
+
+    case DEMANGLE_COMPONENT_SUB_STD:
+      return stab_find_tagged_type (dhandle, info, dc->u.s_string.string,
+                                   dc->u.s_string.len, DEBUG_KIND_ILLEGAL);
+
+    case DEMANGLE_COMPONENT_RESTRICT:
+    case DEMANGLE_COMPONENT_VOLATILE:
+    case DEMANGLE_COMPONENT_CONST:
+    case DEMANGLE_COMPONENT_POINTER:
+    case DEMANGLE_COMPONENT_REFERENCE:
+      dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL,
+                                NULL);
+      if (dt == NULL)
+       return NULL;
+
+      switch (dc->type)
+       {
+       default:
+         abort ();
+       case DEMANGLE_COMPONENT_RESTRICT:
+         /* FIXME: We have no way to represent restrict.  */
+         return dt;
+       case DEMANGLE_COMPONENT_VOLATILE:
+         return debug_make_volatile_type (dhandle, dt);
+       case DEMANGLE_COMPONENT_CONST:
+         return debug_make_const_type (dhandle, dt);
+       case DEMANGLE_COMPONENT_POINTER:
+         return debug_make_pointer_type (dhandle, dt);
+       case DEMANGLE_COMPONENT_REFERENCE:
+         return debug_make_reference_type (dhandle, dt);
+       }
+
+    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
+      {
+       debug_type *pargs;
+       bool varargs;
+
+       if (dc->u.s_binary.left == NULL)
+         {
+           /* In this case the return type is actually unknown.
+              However, I'm not sure this will ever arise in practice;
+              normally an unknown return type would only appear at
+              the top level, which is handled above.  */
+           dt = debug_make_void_type (dhandle);
+         }
+       else
+         dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL,
+                                    NULL);
+       if (dt == NULL)
+         return NULL;
+
+       pargs = stab_demangle_v3_arglist (dhandle, info,
+                                         dc->u.s_binary.right,
+                                         &varargs);
+       if (pargs == NULL)
+         return NULL;
+
+       return debug_make_function_type (dhandle, dt, pargs, varargs);
+      }
+
+    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
+      {
+       char *p;
+       size_t alc;
+       debug_type ret;
+
+       /* We print this component in order to find out the type name.
+          FIXME: Should we instead expose the
+          demangle_builtin_type_info structure?  */
+       p = cplus_demangle_print (DMGL_PARAMS | demangle_flags, dc, 20, &alc);
+       if (p == NULL)
+         {
+           fprintf (stderr, _("Couldn't get demangled builtin type\n"));
+           return NULL;
+         }
+
+       /* The mangling is based on the type, but does not itself
+          indicate what the sizes are.  So we have to guess.  */
+       if (strcmp (p, "signed char") == 0)
+         ret = debug_make_int_type (dhandle, 1, false);
+       else if (strcmp (p, "bool") == 0)
+         ret = debug_make_bool_type (dhandle, 1);
+       else if (strcmp (p, "char") == 0)
+         ret = debug_make_int_type (dhandle, 1, false);
+       else if (strcmp (p, "double") == 0)
+         ret = debug_make_float_type (dhandle, 8);
+       else if (strcmp (p, "long double") == 0)
+         ret = debug_make_float_type (dhandle, 8);
+       else if (strcmp (p, "float") == 0)
+         ret = debug_make_float_type (dhandle, 4);
+       else if (strcmp (p, "__float128") == 0)
+         ret = debug_make_float_type (dhandle, 16);
+       else if (strcmp (p, "unsigned char") == 0)
+         ret = debug_make_int_type (dhandle, 1, true);
+       else if (strcmp (p, "int") == 0)
+         ret = debug_make_int_type (dhandle, 4, false);
+       else if (strcmp (p, "unsigned int") == 0)
+         ret = debug_make_int_type (dhandle, 4, true);
+       else if (strcmp (p, "long") == 0)
+         ret = debug_make_int_type (dhandle, 4, false);
+       else if (strcmp (p, "unsigned long") == 0)
+         ret = debug_make_int_type (dhandle, 4, true);
+       else if (strcmp (p, "__int128") == 0)
+         ret = debug_make_int_type (dhandle, 16, false);
+       else if (strcmp (p, "unsigned __int128") == 0)
+         ret = debug_make_int_type (dhandle, 16, true);
+       else if (strcmp (p, "short") == 0)
+         ret = debug_make_int_type (dhandle, 2, false);
+       else if (strcmp (p, "unsigned short") == 0)
+         ret = debug_make_int_type (dhandle, 2, true);
+       else if (strcmp (p, "void") == 0)
+         ret = debug_make_void_type (dhandle);
+       else if (strcmp (p, "wchar_t") == 0)
+         ret = debug_make_int_type (dhandle, 4, true);
+       else if (strcmp (p, "long long") == 0)
+         ret = debug_make_int_type (dhandle, 8, false);
+       else if (strcmp (p, "unsigned long long") == 0)
+         ret = debug_make_int_type (dhandle, 8, true);
+       else if (strcmp (p, "...") == 0)
+         {
+           if (pvarargs == NULL)
+             fprintf (stderr, _("Unexpected demangled varargs\n"));
+           else
+             *pvarargs = true;
+           ret = NULL;
+         }
+       else
+         {
+           fprintf (stderr, _("Unrecognized demangled builtin type\n"));
+           ret = NULL;
+         }
+
+       free (p);
+
+       return ret;
+      }
+    }
 }
This page took 0.094088 seconds and 4 git commands to generate.