Makefile.in (cplus-dep.o): Use cplus-dem.c from libiberty.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Mon, 17 Aug 1998 11:39:32 +0000 (11:39 +0000)
committerJeff Law <law@gcc.gnu.org>
Mon, 17 Aug 1998 11:39:32 +0000 (05:39 -0600)
        * Makefile.in (cplus-dep.o): Use cplus-dem.c from libiberty.
        * cplus-dem.c: Delete.
        * Makefile.in (fold-const.o): depend on $(RTL_H).
        * fold-const.c: Include rtl.h to get the prototype for
        `set_identifier_local_value'.
        * loop.c (express_from_1): Remove unused variable `tmp'.
        (combine_givs): cast the first argument of bzero to char *.
        * toplev.c (display_help): Remove unused variable `looking_for_start'.

Co-Authored-By: Jeffrey A Law <law@cygnus.com>
From-SVN: r21785

gcc/ChangeLog
gcc/Makefile.in
gcc/cplus-dem.c [deleted file]
gcc/fold-const.c
gcc/loop.c
gcc/toplev.c

index 03141e1370aa13766356818ed7b8737098736526..1c730e797fa4d08b3028bb724ad1a792215c321c 100644 (file)
@@ -12,6 +12,7 @@ Mon Aug 17 10:06:11 1998  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
                          Jeff Law <law@cygnus.com>
 
        * Makefile.in (cplus-dep.o): Use cplus-dem.c from libiberty.
+       * cplus-dem.c: Delete.
 
        * Makefile.in (fold-const.o): depend on $(RTL_H).
 
index 21f4b543d265eb13a78608bba4651aac68d9b303..776a050447095ab0b40e95b3e536ae67f75c00ff 100644 (file)
@@ -1300,7 +1300,7 @@ collect2.o : collect2.c $(CONFIG_H) system.h gansidecl.h gstab.h obstack.h \
 
 tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h
 hash.o: hash.c hash.h system.h toplev.h
-cplus-dem.o: cplus-dem.c $(DEMANGLE_H)
+cplus-dem.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H)
 
 underscore.c: s-under ; @true
 
@@ -1367,7 +1367,8 @@ tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h excep
 print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H)
 stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
    function.h $(EXPR_H) $(RTL_H) toplev.h except.h
-fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h
+fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \
+   $(RTL_H)
 toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) \
    flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
    insn-codes.h insn-config.h $(RECOG_H) Makefile toplev.h dwarfout.h \
diff --git a/gcc/cplus-dem.c b/gcc/cplus-dem.c
deleted file mode 100644 (file)
index d10e9c5..0000000
+++ /dev/null
@@ -1,3852 +0,0 @@
-/* Demangler for GNU C++ 
-   Copyright 1989, 91, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
-   Written by James Clark (jjc@jclark.uucp)
-   Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
-   
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with libiberty; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
-
-   This file imports xmalloc and xrealloc, which are like malloc and
-   realloc except that they generate a fatal error if there is no
-   available memory.  */
-
-/* This file lives in both GCC and libiberty.  When making changes, please
-   try not to break either.  */
-
-#include <ctype.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <demangle.h>
-#undef CURRENT_DEMANGLING_STYLE
-#define CURRENT_DEMANGLING_STYLE work->options
-
-extern char *xmalloc PARAMS((unsigned));
-extern char *xrealloc PARAMS((char *, unsigned));
-
-static const char *mystrstr PARAMS ((const char *, const char *));
-
-static const char *
-mystrstr (s1, s2)
-     const char *s1, *s2;
-{
-  register const char *p = s1;
-  register int len = strlen (s2);
-
-  for (; (p = strchr (p, *s2)) != 0; p++)
-    {
-      if (strncmp (p, s2, len) == 0)
-       {
-         return (p);
-       }
-    }
-  return (0);
-}
-
-/* In order to allow a single demangler executable to demangle strings
-   using various common values of CPLUS_MARKER, as well as any specific
-   one set at compile time, we maintain a string containing all the
-   commonly used ones, and check to see if the marker we are looking for
-   is in that string.  CPLUS_MARKER is usually '$' on systems where the
-   assembler can deal with that.  Where the assembler can't, it's usually
-   '.' (but on many systems '.' is used for other things).  We put the
-   current defined CPLUS_MARKER first (which defaults to '$'), followed
-   by the next most common value, followed by an explicit '$' in case
-   the value of CPLUS_MARKER is not '$'.
-
-   We could avoid this if we could just get g++ to tell us what the actual
-   cplus marker character is as part of the debug information, perhaps by
-   ensuring that it is the character that terminates the gcc<n>_compiled
-   marker symbol (FIXME).  */
-
-#if !defined (CPLUS_MARKER)
-#define CPLUS_MARKER '$'
-#endif
-
-enum demangling_styles current_demangling_style = gnu_demangling;
-
-static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
-
-void
-set_cplus_marker_for_demangling (ch)
-     int ch;
-{
-  cplus_markers[0] = ch;
-}
-
-typedef struct string          /* Beware: these aren't required to be */
-{                              /*  '\0' terminated.  */
-  char *b;                     /* pointer to start of string */
-  char *p;                     /* pointer after last character */
-  char *e;                     /* pointer after end of allocated space */
-} string;
-
-/* Stuff that is shared between sub-routines.
-   Using a shared structure allows cplus_demangle to be reentrant.  */
-
-struct work_stuff
-{
-  int options;
-  char **typevec;
-  char **ktypevec;
-  char **btypevec;
-  int numk;
-  int numb;
-  int ksize;
-  int bsize;
-  int ntypes;
-  int typevec_size;
-  int constructor;
-  int destructor;
-  int static_type;     /* A static member function */
-  int const_type;      /* A const member function */
-  int volatile_type;    /* A volatile member function */
-  char **tmpl_argvec;   /* Template function arguments. */
-  int ntmpl_args;       /* The number of template function arguments. */
-  int forgetting_types; /* Nonzero if we are not remembering the types
-                          we see.  */
-  string* previous_argument; /* The last function argument demangled.  */
-  int nrepeats;         /* The number of times to repeat the previous
-                          argument.  */
-};
-
-#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
-#define PRINT_ARG_TYPES       (work -> options & DMGL_PARAMS)
-
-static const struct optable
-{
-  const char *in;
-  const char *out;
-  int flags;
-} optable[] = {
-  {"nw",         " new",       DMGL_ANSI},     /* new (1.92,    ansi) */
-  {"dl",         " delete",    DMGL_ANSI},     /* new (1.92,    ansi) */
-  {"new",        " new",       0},             /* old (1.91,    and 1.x) */
-  {"delete",     " delete",    0},             /* old (1.91,    and 1.x) */
-  {"vn",         " new []",    DMGL_ANSI},     /* GNU, pending ansi */
-  {"vd",         " delete []", DMGL_ANSI},     /* GNU, pending ansi */
-  {"as",         "=",          DMGL_ANSI},     /* ansi */
-  {"ne",         "!=",         DMGL_ANSI},     /* old, ansi */
-  {"eq",         "==",         DMGL_ANSI},     /* old, ansi */
-  {"ge",         ">=",         DMGL_ANSI},     /* old, ansi */
-  {"gt",         ">",          DMGL_ANSI},     /* old, ansi */
-  {"le",         "<=",         DMGL_ANSI},     /* old, ansi */
-  {"lt",         "<",          DMGL_ANSI},     /* old, ansi */
-  {"plus",       "+",          0},             /* old */
-  {"pl",         "+",          DMGL_ANSI},     /* ansi */
-  {"apl",        "+=",         DMGL_ANSI},     /* ansi */
-  {"minus",      "-",          0},             /* old */
-  {"mi",         "-",          DMGL_ANSI},     /* ansi */
-  {"ami",        "-=",         DMGL_ANSI},     /* ansi */
-  {"mult",       "*",          0},             /* old */
-  {"ml",         "*",          DMGL_ANSI},     /* ansi */
-  {"amu",        "*=",         DMGL_ANSI},     /* ansi (ARM/Lucid) */
-  {"aml",        "*=",         DMGL_ANSI},     /* ansi (GNU/g++) */
-  {"convert",    "+",          0},             /* old (unary +) */
-  {"negate",     "-",          0},             /* old (unary -) */
-  {"trunc_mod",          "%",          0},             /* old */
-  {"md",         "%",          DMGL_ANSI},     /* ansi */
-  {"amd",        "%=",         DMGL_ANSI},     /* ansi */
-  {"trunc_div",          "/",          0},             /* old */
-  {"dv",         "/",          DMGL_ANSI},     /* ansi */
-  {"adv",        "/=",         DMGL_ANSI},     /* ansi */
-  {"truth_andif", "&&",                0},             /* old */
-  {"aa",         "&&",         DMGL_ANSI},     /* ansi */
-  {"truth_orif",  "||",                0},             /* old */
-  {"oo",         "||",         DMGL_ANSI},     /* ansi */
-  {"truth_not",          "!",          0},             /* old */
-  {"nt",         "!",          DMGL_ANSI},     /* ansi */
-  {"postincrement","++",       0},             /* old */
-  {"pp",         "++",         DMGL_ANSI},     /* ansi */
-  {"postdecrement","--",       0},             /* old */
-  {"mm",         "--",         DMGL_ANSI},     /* ansi */
-  {"bit_ior",    "|",          0},             /* old */
-  {"or",         "|",          DMGL_ANSI},     /* ansi */
-  {"aor",        "|=",         DMGL_ANSI},     /* ansi */
-  {"bit_xor",    "^",          0},             /* old */
-  {"er",         "^",          DMGL_ANSI},     /* ansi */
-  {"aer",        "^=",         DMGL_ANSI},     /* ansi */
-  {"bit_and",    "&",          0},             /* old */
-  {"ad",         "&",          DMGL_ANSI},     /* ansi */
-  {"aad",        "&=",         DMGL_ANSI},     /* ansi */
-  {"bit_not",    "~",          0},             /* old */
-  {"co",         "~",          DMGL_ANSI},     /* ansi */
-  {"call",       "()",         0},             /* old */
-  {"cl",         "()",         DMGL_ANSI},     /* ansi */
-  {"alshift",    "<<",         0},             /* old */
-  {"ls",         "<<",         DMGL_ANSI},     /* ansi */
-  {"als",        "<<=",        DMGL_ANSI},     /* ansi */
-  {"arshift",    ">>",         0},             /* old */
-  {"rs",         ">>",         DMGL_ANSI},     /* ansi */
-  {"ars",        ">>=",        DMGL_ANSI},     /* ansi */
-  {"component",          "->",         0},             /* old */
-  {"pt",         "->",         DMGL_ANSI},     /* ansi; Lucid C++ form */
-  {"rf",         "->",         DMGL_ANSI},     /* ansi; ARM/GNU form */
-  {"indirect",   "*",          0},             /* old */
-  {"method_call",  "->()",     0},             /* old */
-  {"addr",       "&",          0},             /* old (unary &) */
-  {"array",      "[]",         0},             /* old */
-  {"vc",         "[]",         DMGL_ANSI},     /* ansi */
-  {"compound",   ", ",         0},             /* old */
-  {"cm",         ", ",         DMGL_ANSI},     /* ansi */
-  {"cond",       "?:",         0},             /* old */
-  {"cn",         "?:",         DMGL_ANSI},     /* pseudo-ansi */
-  {"max",        ">?",         0},             /* old */
-  {"mx",         ">?",         DMGL_ANSI},     /* pseudo-ansi */
-  {"min",        "<?",         0},             /* old */
-  {"mn",         "<?",         DMGL_ANSI},     /* pseudo-ansi */
-  {"nop",        "",           0},             /* old (for operator=) */
-  {"rm",         "->*",        DMGL_ANSI},     /* ansi */
-  {"sz",          "sizeof ",    DMGL_ANSI}      /* pseudo-ansi */
-};
-
-/* These values are used to indicate the various type varieties.
-   They are all non-zero so that they can be used as `success'
-   values.  */
-typedef enum type_kind_t 
-{ 
-  tk_none,
-  tk_pointer,
-  tk_integral, 
-  tk_bool,
-  tk_char, 
-  tk_real
-} type_kind_t;
-                            
-#define STRING_EMPTY(str)      ((str) -> b == (str) -> p)
-#define PREPEND_BLANK(str)     {if (!STRING_EMPTY(str)) \
-    string_prepend(str, " ");}
-#define APPEND_BLANK(str)      {if (!STRING_EMPTY(str)) \
-    string_append(str, " ");}
-#define LEN_STRING(str)         ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
-
-/* The scope separator appropriate for the language being demangled.  */
-#define SCOPE_STRING(work) "::"
-
-#define ARM_VTABLE_STRING "__vtbl__"   /* Lucid/ARM virtual table prefix */
-#define ARM_VTABLE_STRLEN 8            /* strlen (ARM_VTABLE_STRING) */
-
-/* Prototypes for local functions */
-
-static char *
-mop_up PARAMS ((struct work_stuff *, string *, int));
-
-static void
-squangle_mop_up PARAMS ((struct work_stuff *));
-
-#if 0
-static int
-demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
-#endif
-
-static char *
-internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
-
-static int
-demangle_template_template_parm PARAMS ((struct work_stuff *work, 
-                                        const char **, string *));
-
-static int
-demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
-                          string *, int, int));
-
-static int
-arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
-               const char **));
-
-static void
-demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
-
-static int
-demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
-                           int, int));
-
-static int
-demangle_class PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-gnu_special PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-arm_special PARAMS ((const char **, string *));
-
-static void
-string_need PARAMS ((string *, int));
-
-static void
-string_delete PARAMS ((string *));
-
-static void
-string_init PARAMS ((string *));
-
-static void
-string_clear PARAMS ((string *));
-
-#if 0
-static int
-string_empty PARAMS ((string *));
-#endif
-
-static void
-string_append PARAMS ((string *, const char *));
-
-static void
-string_appends PARAMS ((string *, string *));
-
-static void
-string_appendn PARAMS ((string *, const char *, int));
-
-static void
-string_prepend PARAMS ((string *, const char *));
-
-static void
-string_prependn PARAMS ((string *, const char *, int));
-
-static int
-get_count PARAMS ((const char **, int *));
-
-static int
-consume_count PARAMS ((const char **));
-
-static int 
-consume_count_with_underscores PARAMS ((const char**));
-
-static int
-demangle_args PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
-
-static int
-do_type PARAMS ((struct work_stuff *, const char **, string *));
-
-static int
-do_arg PARAMS ((struct work_stuff *, const char **, string *));
-
-static void
-demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
-                               const char *));
-
-static void
-remember_type PARAMS ((struct work_stuff *, const char *, int));
-
-static void
-remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
-
-static int
-register_Btype PARAMS ((struct work_stuff *));
-
-static void
-remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
-
-static void
-forget_types PARAMS ((struct work_stuff *));
-
-static void
-forget_B_and_K_types PARAMS ((struct work_stuff *));
-
-static void
-string_prepends PARAMS ((string *, string *));
-
-static int 
-demangle_template_value_parm PARAMS ((struct work_stuff*, const char**, 
-                                     string*, type_kind_t));
-
-/*  Translate count to integer, consuming tokens in the process.
-    Conversion terminates on the first non-digit character.
-    Trying to consume something that isn't a count results in
-    no consumption of input and a return of 0.  */
-
-static int
-consume_count (type)
-     const char **type;
-{
-  int count = 0;
-
-  while (isdigit (**type))
-    {
-      count *= 10;
-      count += **type - '0';
-      (*type)++;
-    }
-  return (count);
-}
-
-
-/* Like consume_count, but for counts that are preceded and followed
-   by '_' if they are greater than 10.  Also, -1 is returned for
-   failure, since 0 can be a valid value.  */
-
-static int
-consume_count_with_underscores (mangled)
-     const char **mangled;
-{
-  int idx;
-
-  if (**mangled == '_')
-    {
-      (*mangled)++;
-      if (!isdigit (**mangled))
-       return -1;
-
-      idx = consume_count (mangled);
-      if (**mangled != '_')
-       /* The trailing underscore was missing. */
-       return -1;
-           
-      (*mangled)++;
-    }
-  else
-    {
-      if (**mangled < '0' || **mangled > '9')
-       return -1;
-           
-      idx = **mangled - '0';
-      (*mangled)++;
-    }
-
-  return idx;
-}
-
-int
-cplus_demangle_opname (opname, result, options)
-     const char *opname;
-     char *result;
-     int options;
-{
-  int len, len1, ret;
-  string type;
-  struct work_stuff work[1];
-  const char *tem;
-
-  len = strlen(opname);
-  result[0] = '\0';
-  ret = 0;
-  memset ((char *) work, 0, sizeof (work));
-  work->options = options;
-  
-  if (opname[0] == '_' && opname[1] == '_'
-      && opname[2] == 'o' && opname[3] == 'p')
-    {
-      /* ANSI.  */
-      /* type conversion operator.  */
-      tem = opname + 4;
-      if (do_type (work, &tem, &type))
-       {
-         strcat (result, "operator ");
-         strncat (result, type.b, type.p - type.b);
-         string_delete (&type);
-         ret = 1;
-       }
-    }
-  else if (opname[0] == '_' && opname[1] == '_'
-          && opname[2] >= 'a' && opname[2] <= 'z'
-          && opname[3] >= 'a' && opname[3] <= 'z')
-    {
-      if (opname[4] == '\0')
-       {
-         /* Operator.  */
-         size_t i;
-         for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-           {
-             if (strlen (optable[i].in) == 2
-                 && memcmp (optable[i].in, opname + 2, 2) == 0)
-               {
-                 strcat (result, "operator");
-                 strcat (result, optable[i].out);
-                 ret = 1;
-                 break;
-               }
-           }
-       }
-      else
-       {
-         if (opname[2] == 'a' && opname[5] == '\0')
-           {
-             /* Assignment.  */
-             size_t i;
-             for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-               {
-                 if (strlen (optable[i].in) == 3
-                     && memcmp (optable[i].in, opname + 2, 3) == 0)
-                   {
-                     strcat (result, "operator");
-                     strcat (result, optable[i].out);
-                     ret = 1;
-                     break;
-                   }                 
-               }
-           }
-       }
-    }
-  else if (len >= 3 
-          && opname[0] == 'o'
-          && opname[1] == 'p'
-          && strchr (cplus_markers, opname[2]) != NULL)
-    {
-      /* see if it's an assignment expression */
-      if (len >= 10 /* op$assign_ */
-         && memcmp (opname + 3, "assign_", 7) == 0)
-       {
-         size_t i;
-         for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-           {
-             len1 = len - 10;
-             if (strlen (optable[i].in) == len1
-                 && memcmp (optable[i].in, opname + 10, len1) == 0)
-               {
-                 strcat (result, "operator");
-                 strcat (result, optable[i].out);
-                 strcat (result, "=");
-                 ret = 1;
-                 break;
-               }
-           }
-       }
-      else
-       {
-         size_t i;
-         for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-           {
-             len1 = len - 3;
-             if (strlen (optable[i].in) == len1 
-                 && memcmp (optable[i].in, opname + 3, len1) == 0)
-               {
-                 strcat (result, "operator");
-                 strcat (result, optable[i].out);
-                 ret = 1;
-                 break;
-               }
-           }
-       }
-    }
-  else if (len >= 5 && memcmp (opname, "type", 4) == 0
-          && strchr (cplus_markers, opname[4]) != NULL)
-    {
-      /* type conversion operator */
-      tem = opname + 5;
-      if (do_type (work, &tem, &type))
-       {
-         strcat (result, "operator ");
-         strncat (result, type.b, type.p - type.b);
-         string_delete (&type);
-         ret = 1;
-       }
-    }
-  squangle_mop_up (work);
-  return ret;
-
-}
-/* Takes operator name as e.g. "++" and returns mangled
-   operator name (e.g. "postincrement_expr"), or NULL if not found.
-
-   If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
-   if OPTIONS & DMGL_ANSI == 0, return the old GNU name.  */
-
-const char *
-cplus_mangle_opname (opname, options)
-     const char *opname;
-     int options;
-{
-  size_t i;
-  int len;
-
-  len = strlen (opname);
-  for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-    {
-      if (strlen (optable[i].out) == len
-         && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
-         && memcmp (optable[i].out, opname, len) == 0)
-       return optable[i].in;
-    }
-  return (0);
-}
-
-/* char *cplus_demangle (const char *mangled, int options)
-
-   If MANGLED is a mangled function name produced by GNU C++, then
-   a pointer to a malloced string giving a C++ representation
-   of the name will be returned; otherwise NULL will be returned.
-   It is the caller's responsibility to free the string which
-   is returned.
-
-   The OPTIONS arg may contain one or more of the following bits:
-
-       DMGL_ANSI       ANSI qualifiers such as `const' and `void' are
-                       included.
-       DMGL_PARAMS     Function parameters are included.
-
-   For example,
-   
-   cplus_demangle ("foo__1Ai", DMGL_PARAMS)            => "A::foo(int)"
-   cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI)        => "A::foo(int)"
-   cplus_demangle ("foo__1Ai", 0)                      => "A::foo"
-
-   cplus_demangle ("foo__1Afe", DMGL_PARAMS)           => "A::foo(float,...)"
-   cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
-   cplus_demangle ("foo__1Afe", 0)                     => "A::foo"
-
-   Note that any leading underscores, or other such characters prepended by
-   the compilation system, are presumed to have already been stripped from
-   MANGLED.  */
-
-char *
-cplus_demangle (mangled, options)
-     const char *mangled;
-     int options;
-{
-  char *ret;
-  struct work_stuff work[1];
-  memset ((char *) work, 0, sizeof (work));
-  work -> options = options;
-  if ((work -> options & DMGL_STYLE_MASK) == 0)
-    work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
-
-  ret = internal_cplus_demangle (work, mangled);
-  squangle_mop_up (work);
-  return (ret);
-}
-  
-
-/* This function performs most of what cplus_demangle use to do, but 
-   to be able to demangle a name with a B, K or n code, we need to
-   have a longer term memory of what types have been seen. The original
-   now intializes and cleans up the squangle code info, while internal
-   calls go directly to this routine to avoid resetting that info. */
-
-static char *
-internal_cplus_demangle (work, mangled)
-     struct work_stuff *work;
-     const char *mangled;
-{
-
-  string decl;
-  int success = 0;
-  char *demangled = NULL;
-  int s1,s2,s3,s4;
-  int saved_volatile_type;
-  s1 = work->constructor;
-  s2 = work->destructor;
-  s3 = work->static_type;
-  s4 = work->const_type;
-  saved_volatile_type = work->volatile_type;
-  work->constructor = work->destructor = 0;
-  work->static_type = work->const_type = 0;
-  work->volatile_type = 0;
-
-  if ((mangled != NULL) && (*mangled != '\0'))
-    {
-      string_init (&decl);
-
-      /* First check to see if gnu style demangling is active and if the
-        string to be demangled contains a CPLUS_MARKER.  If so, attempt to
-        recognize one of the gnu special forms rather than looking for a
-        standard prefix.  In particular, don't worry about whether there
-        is a "__" string in the mangled string.  Consider "_$_5__foo" for
-        example.  */
-
-      if ((AUTO_DEMANGLING || GNU_DEMANGLING))
-       {
-         success = gnu_special (work, &mangled, &decl);
-       }
-      if (!success)
-       {
-         success = demangle_prefix (work, &mangled, &decl);
-       }
-      if (success && (*mangled != '\0'))
-       {
-         success = demangle_signature (work, &mangled, &decl);
-       }
-      if (work->constructor == 2)
-        {
-          string_prepend (&decl, "global constructors keyed to ");
-          work->constructor = 0;
-        }
-      else if (work->destructor == 2)
-        {
-          string_prepend (&decl, "global destructors keyed to ");
-          work->destructor = 0;
-        }
-      demangled = mop_up (work, &decl, success);
-    }
-  work->constructor = s1;
-  work->destructor = s2;
-  work->static_type = s3;
-  work->const_type = s4;
-  work->volatile_type = saved_volatile_type;
-  return (demangled);
-}
-
-
-/* Clear out and squangling related storage */
-static void
-squangle_mop_up (work)
-     struct work_stuff *work;
-{
-  /* clean up the B and K type mangling types. */
-  forget_B_and_K_types (work);
-  if (work -> btypevec != NULL)
-    {
-      free ((char *) work -> btypevec);
-    }
-  if (work -> ktypevec != NULL)
-    {
-      free ((char *) work -> ktypevec);
-    }
-}
-
-/* Clear out any mangled storage */
-
-static char *
-mop_up (work, declp, success)
-     struct work_stuff *work;
-     string *declp;
-     int success;
-{
-  char *demangled = NULL;
-
-  /* Discard the remembered types, if any.  */
-  
-  forget_types (work);
-  if (work -> typevec != NULL)
-    {
-      free ((char *) work -> typevec);
-      work -> typevec = NULL;
-    }
-  if (work->tmpl_argvec)
-    {
-      int i;
-
-      for (i = 0; i < work->ntmpl_args; i++)
-       if (work->tmpl_argvec[i])
-         free ((char*) work->tmpl_argvec[i]);
-      
-      free ((char*) work->tmpl_argvec);
-      work->tmpl_argvec = NULL;
-    }
-  if (work->previous_argument)
-    {
-      string_delete (work->previous_argument);
-      free ((char*) work->previous_argument);
-    }
-
-  /* If demangling was successful, ensure that the demangled string is null
-     terminated and return it.  Otherwise, free the demangling decl.  */
-  
-  if (!success)
-    {
-      string_delete (declp);
-    }
-  else
-    {
-      string_appendn (declp, "", 1);
-      demangled = declp -> b;
-    }
-  return (demangled);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       demangle_signature -- demangle the signature part of a mangled name
-
-SYNOPSIS
-
-       static int
-       demangle_signature (struct work_stuff *work, const char **mangled,
-                           string *declp);
-
-DESCRIPTION
-
-       Consume and demangle the signature portion of the mangled name.
-
-       DECLP is the string where demangled output is being built.  At
-       entry it contains the demangled root name from the mangled name
-       prefix.  I.E. either a demangled operator name or the root function
-       name.  In some special cases, it may contain nothing.
-
-       *MANGLED points to the current unconsumed location in the mangled
-       name.  As tokens are consumed and demangling is performed, the
-       pointer is updated to continuously point at the next token to
-       be consumed.
-
-       Demangling GNU style mangled names is nasty because there is no
-       explicit token that marks the start of the outermost function
-       argument list.  */
-
-static int
-demangle_signature (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  int success = 1;
-  int func_done = 0;
-  int expect_func = 0;
-  int expect_return_type = 0;
-  const char *oldmangled = NULL;
-  string trawname;
-  string tname;
-
-  while (success && (**mangled != '\0'))
-    {
-      switch (**mangled)
-       {
-       case 'Q':
-         oldmangled = *mangled;
-         success = demangle_qualified (work, mangled, declp, 1, 0);
-         if (success)
-           remember_type (work, oldmangled, *mangled - oldmangled);
-         if (AUTO_DEMANGLING || GNU_DEMANGLING)
-           expect_func = 1;
-         oldmangled = NULL;
-         break;
-
-        case 'K':
-         oldmangled = *mangled;
-         success = demangle_qualified (work, mangled, declp, 1, 0);
-         if (AUTO_DEMANGLING || GNU_DEMANGLING)
-           {
-             expect_func = 1;
-           }
-         oldmangled = NULL;
-         break;
-         
-       case 'S':
-         /* Static member function */
-         if (oldmangled == NULL)
-           {
-             oldmangled = *mangled;
-           }
-         (*mangled)++;
-         work -> static_type = 1;
-         break;
-
-       case 'C':
-       case 'V':
-         if (**mangled == 'C')
-           work -> const_type = 1;
-         else
-           work->volatile_type = 1;
-
-         /* a qualified member function */
-         if (oldmangled == NULL)
-           oldmangled = *mangled;
-         (*mangled)++;
-         break;
-         
-       case '0': case '1': case '2': case '3': case '4':
-       case '5': case '6': case '7': case '8': case '9':
-         if (oldmangled == NULL)
-           {
-             oldmangled = *mangled;
-           }
-         success = demangle_class (work, mangled, declp);
-         if (success)
-           {
-             remember_type (work, oldmangled, *mangled - oldmangled);
-           }
-         if (AUTO_DEMANGLING || GNU_DEMANGLING)
-           {
-             expect_func = 1;
-           }
-         oldmangled = NULL;
-         break;
-
-       case 'B':
-         {
-           string s;
-           success = do_type (work, mangled, &s);
-           if (success)
-             {
-               string_append (&s, SCOPE_STRING (work));
-               string_prepends (declp, &s);
-             }
-           oldmangled = NULL;
-           expect_func = 1;
-         }
-         break;
-
-       case 'F':
-         /* Function */
-         /* ARM style demangling includes a specific 'F' character after
-            the class name.  For GNU style, it is just implied.  So we can
-            safely just consume any 'F' at this point and be compatible
-            with either style.  */
-
-         oldmangled = NULL;
-         func_done = 1;
-         (*mangled)++;
-
-         /* For lucid/ARM style we have to forget any types we might
-            have remembered up to this point, since they were not argument
-            types.  GNU style considers all types seen as available for
-            back references.  See comment in demangle_args() */
-
-         if (LUCID_DEMANGLING || ARM_DEMANGLING)
-           {
-             forget_types (work);
-           }
-         success = demangle_args (work, mangled, declp);
-         break;
-         
-       case 't':
-         /* G++ Template */
-         string_init(&trawname); 
-         string_init(&tname);
-         if (oldmangled == NULL)
-           {
-             oldmangled = *mangled;
-           }
-         success = demangle_template (work, mangled, &tname,
-                                      &trawname, 1, 1);
-         if (success)
-           {
-             remember_type (work, oldmangled, *mangled - oldmangled);
-           }
-         string_append (&tname, SCOPE_STRING (work));
-
-         string_prepends(declp, &tname);
-         if (work -> destructor & 1)
-           {
-             string_prepend (&trawname, "~");
-             string_appends (declp, &trawname);
-             work->destructor -= 1;
-           }
-         if ((work->constructor & 1) || (work->destructor & 1))
-           {
-             string_appends (declp, &trawname);
-             work->constructor -= 1;
-           }
-         string_delete(&trawname);
-         string_delete(&tname);
-         oldmangled = NULL;
-         expect_func = 1;
-         break;
-
-       case '_':
-         if (GNU_DEMANGLING && expect_return_type) 
-           {
-             /* Read the return type. */
-             string return_type;
-             string_init (&return_type);
-
-             (*mangled)++;
-             success = do_type (work, mangled, &return_type);
-             APPEND_BLANK (&return_type);
-
-             string_prepends (declp, &return_type);
-             string_delete (&return_type);
-             break;
-           }
-         else
-           /* At the outermost level, we cannot have a return type specified,
-              so if we run into another '_' at this point we are dealing with
-              a mangled name that is either bogus, or has been mangled by
-              some algorithm we don't know how to deal with.  So just
-              reject the entire demangling.  */
-           success = 0;
-         break;
-
-       case 'H':
-         if (GNU_DEMANGLING) 
-           {
-             /* A G++ template function.  Read the template arguments. */
-             success = demangle_template (work, mangled, declp, 0, 0,
-                                          0);
-             if (!(work->constructor & 1))
-               expect_return_type = 1;
-             (*mangled)++;
-             break;
-           }
-         else
-           /* fall through */
-           {;}
-
-       default:
-         if (AUTO_DEMANGLING || GNU_DEMANGLING)
-           {
-             /* Assume we have stumbled onto the first outermost function
-                argument token, and start processing args.  */
-             func_done = 1;
-             success = demangle_args (work, mangled, declp);
-           }
-         else
-           {
-             /* Non-GNU demanglers use a specific token to mark the start
-                of the outermost function argument tokens.  Typically 'F',
-                for ARM-demangling, for example.  So if we find something
-                we are not prepared for, it must be an error.  */
-             success = 0;
-           }
-         break;
-       }
-      /*
-       if (AUTO_DEMANGLING || GNU_DEMANGLING)
-       */
-      {
-       if (success && expect_func)
-         {
-           func_done = 1;
-           success = demangle_args (work, mangled, declp);
-           /* Since template include the mangling of their return types,
-              we must set expect_func to 0 so that we don't try do
-              demangle more arguments the next time we get here.  */
-           expect_func = 0;
-         }
-      }
-    }
-  if (success && !func_done)
-    {
-      if (AUTO_DEMANGLING || GNU_DEMANGLING)
-       {
-         /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
-            bar__3fooi is 'foo::bar(int)'.  We get here when we find the
-            first case, and need to ensure that the '(void)' gets added to
-            the current declp.  Note that with ARM, the first case
-            represents the name of a static data member 'foo::bar',
-            which is in the current declp, so we leave it alone.  */
-         success = demangle_args (work, mangled, declp);
-       }
-    }
-  if (success && work -> static_type && PRINT_ARG_TYPES)
-    string_append (declp, " static");
-  if (success && work -> const_type && PRINT_ARG_TYPES)
-    string_append (declp, " const");
-  else if (success && work->volatile_type && PRINT_ARG_TYPES)
-    string_append (declp, " volatile");
-
-  return (success);
-}
-
-#if 0
-
-static int
-demangle_method_args (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  int success = 0;
-
-  if (work -> static_type)
-    {
-      string_append (declp, *mangled + 1);
-      *mangled += strlen (*mangled);
-      success = 1;
-    }
-  else
-    {
-      success = demangle_args (work, mangled, declp);
-    }
-  return (success);
-}
-
-#endif
-
-static int
-demangle_template_template_parm (work, mangled, tname)
-     struct work_stuff *work;
-     const char **mangled;
-     string *tname;
-{
-  int i;
-  int r;
-  int need_comma = 0;
-  int success = 1;
-  string temp;
-
-  string_append (tname, "template <");
-  /* get size of template parameter list */
-  if (get_count (mangled, &r))
-    {
-      for (i = 0; i < r; i++)
-       {
-         if (need_comma)
-           {
-             string_append (tname, ", ");
-           }
-
-           /* Z for type parameters */
-           if (**mangled == 'Z')
-             {
-               (*mangled)++;
-               string_append (tname, "class");
-             }
-             /* z for template parameters */
-           else if (**mangled == 'z')
-             {
-               (*mangled)++;
-               success = 
-                 demangle_template_template_parm (work, mangled, tname);
-               if (!success)
-                 {
-                   break;
-                 }
-             }
-           else
-             {
-               /* temp is initialized in do_type */
-               success = do_type (work, mangled, &temp);
-               if (success)
-                 {
-                   string_appends (tname, &temp);
-                 }
-               string_delete(&temp);
-               if (!success)
-                 {
-                   break;
-                 }
-             }
-         need_comma = 1;
-       }
-
-    }
-  if (tname->p[-1] == '>')
-    string_append (tname, " ");
-  string_append (tname, "> class");
-  return (success);
-}
-
-static int
-demangle_integral_value (work, mangled, s)
-     struct work_stuff *work;
-     const char** mangled;
-     string* s;
-{
-  int success;
-
-  if (**mangled == 'E')
-    {
-      int need_operator = 0;
-      
-      success = 1;
-      string_appendn (s, "(", 1);
-      (*mangled)++;
-      while (success && **mangled != 'W' && **mangled != '\0')
-       {
-         if (need_operator)
-           {
-             size_t i;
-             size_t len;
-
-             success = 0;
-
-             len = strlen (*mangled);
-
-             for (i = 0; 
-                  i < sizeof (optable) / sizeof (optable [0]);
-                  ++i)
-               {
-                 size_t l = strlen (optable[i].in);
-
-                 if (l <= len
-                     && memcmp (optable[i].in, *mangled, l) == 0)
-                   {
-                     string_appendn (s, " ", 1);
-                     string_append (s, optable[i].out);
-                     string_appendn (s, " ", 1);
-                     success = 1;
-                     (*mangled) += l;
-                     break;
-                   }
-               }
-
-             if (!success)
-               break;
-           }
-         else
-           need_operator = 1;
-
-         success = demangle_template_value_parm (work, mangled, s,
-                                                 tk_integral);
-       }
-
-      if (**mangled != 'W')
-         success = 0;
-      else 
-       {
-         string_appendn (s, ")", 1);
-         (*mangled)++;
-       }
-    }
-  else if (**mangled == 'Q' || **mangled == 'K')
-    success = demangle_qualified (work, mangled, s, 0, 1);
-  else
-    {
-      success = 0;
-
-      if (**mangled == 'm')
-       {
-         string_appendn (s, "-", 1);
-         (*mangled)++;
-       }
-      while (isdigit (**mangled))      
-       {
-         string_appendn (s, *mangled, 1);
-         (*mangled)++;
-         success = 1;
-       }
-    }
-  
-  return success;
-}
-
-static int 
-demangle_template_value_parm (work, mangled, s, tk)
-     struct work_stuff *work;
-     const char **mangled;
-     string* s;
-     type_kind_t tk;
-{
-  int success = 1;
-
-  if (**mangled == 'Y')
-    {
-      /* The next argument is a template parameter. */
-      int idx;
-
-      (*mangled)++;
-      idx = consume_count_with_underscores (mangled);
-      if (idx == -1 
-         || (work->tmpl_argvec && idx >= work->ntmpl_args)
-         || consume_count_with_underscores (mangled) == -1)
-       return -1;
-      if (work->tmpl_argvec)
-       string_append (s, work->tmpl_argvec[idx]);
-      else
-       {
-         char buf[10];
-         sprintf(buf, "T%d", idx);
-         string_append (s, buf);
-       }
-    }
-  else if (tk == tk_integral)
-    success = demangle_integral_value (work, mangled, s);
-  else if (tk == tk_char)
-    {
-      char tmp[2];
-      int val;
-      if (**mangled == 'm')
-       {
-         string_appendn (s, "-", 1);
-         (*mangled)++;
-       }
-      string_appendn (s, "'", 1);
-      val = consume_count(mangled);
-      if (val == 0)
-       return -1;
-      tmp[0] = (char)val;
-      tmp[1] = '\0';
-      string_appendn (s, &tmp[0], 1);
-      string_appendn (s, "'", 1);
-    }
-  else if (tk == tk_bool)
-    {
-      int val = consume_count (mangled);
-      if (val == 0)
-       string_appendn (s, "false", 5);
-      else if (val == 1)
-       string_appendn (s, "true", 4);
-      else
-       success = 0;
-    }
-  else if (tk == tk_real)
-    {
-      if (**mangled == 'm')
-       {
-         string_appendn (s, "-", 1);
-         (*mangled)++;
-       }
-      while (isdigit (**mangled))      
-       {
-         string_appendn (s, *mangled, 1);
-         (*mangled)++;
-       }
-      if (**mangled == '.') /* fraction */
-       {
-         string_appendn (s, ".", 1);
-         (*mangled)++;
-         while (isdigit (**mangled))   
-           {
-             string_appendn (s, *mangled, 1);
-             (*mangled)++;
-           }
-       }
-      if (**mangled == 'e') /* exponent */
-       {
-         string_appendn (s, "e", 1);
-         (*mangled)++;
-         while (isdigit (**mangled))   
-           {
-             string_appendn (s, *mangled, 1);
-             (*mangled)++;
-           }
-       }
-    }
-  else if (tk == tk_pointer)
-    {
-      int symbol_len = consume_count (mangled);
-      if (symbol_len == 0)
-       return -1;
-      if (symbol_len == 0)
-       string_appendn (s, "0", 1);
-      else
-       {
-         char *p = xmalloc (symbol_len + 1), *q;
-         strncpy (p, *mangled, symbol_len);
-         p [symbol_len] = '\0';
-         q = internal_cplus_demangle (work, p);
-         string_appendn (s, "&", 1);
-         if (q)
-           {
-             string_append (s, q);
-             free (q);
-           }
-         else
-           string_append (s, p);
-         free (p);
-       }
-      *mangled += symbol_len;
-    }
-
-  return success;
-}
-
-/* Demangle the template name in MANGLED.  The full name of the
-   template (e.g., S<int>) is placed in TNAME.  The name without the
-   template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
-   non-NULL.  If IS_TYPE is nonzero, this template is a type template,
-   not a function template.  If both IS_TYPE and REMEMBER are nonzero,
-   the tmeplate is remembered in the list of back-referenceable
-   types.  */
-
-static int
-demangle_template (work, mangled, tname, trawname, is_type, remember)
-     struct work_stuff *work;
-     const char **mangled;
-     string *tname;
-     string *trawname;
-     int is_type;
-     int remember;
-{
-  int i;
-  int r;
-  int need_comma = 0;
-  int success = 0;
-  const char *start;
-  string temp;
-  int bindex;
-
-  (*mangled)++;
-  if (is_type)
-    {
-      if (remember)
-       bindex = register_Btype (work);
-      start = *mangled;
-      /* get template name */
-      if (**mangled == 'z')
-       {
-         int idx;
-         (*mangled)++;
-         (*mangled)++;
-
-         idx = consume_count_with_underscores (mangled);
-         if (idx == -1 
-             || (work->tmpl_argvec && idx >= work->ntmpl_args)
-             || consume_count_with_underscores (mangled) == -1)
-           return (0);
-
-         if (work->tmpl_argvec)
-           {
-             string_append (tname, work->tmpl_argvec[idx]);
-             if (trawname)
-               string_append (trawname, work->tmpl_argvec[idx]);
-           }
-         else
-           {
-             char buf[10];
-             sprintf(buf, "T%d", idx);
-             string_append (tname, buf);
-             if (trawname)
-               string_append (trawname, buf);
-           }
-       }
-      else
-       {
-         if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
-           {
-             return (0);
-           }
-         string_appendn (tname, *mangled, r);
-         if (trawname)
-           string_appendn (trawname, *mangled, r);
-         *mangled += r;
-       }
-    }
-  string_append (tname, "<");
-  /* get size of template parameter list */
-  if (!get_count (mangled, &r))
-    {
-      return (0);
-    }
-  if (!is_type)
-    {
-      /* Create an array for saving the template argument values. */
-      work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
-      work->ntmpl_args = r;
-      for (i = 0; i < r; i++)
-       work->tmpl_argvec[i] = 0;
-    }
-  for (i = 0; i < r; i++)
-    {
-      if (need_comma)
-       {
-         string_append (tname, ", ");
-       }
-      /* Z for type parameters */
-      if (**mangled == 'Z')
-       {
-         (*mangled)++;
-         /* temp is initialized in do_type */
-         success = do_type (work, mangled, &temp);
-         if (success)
-           {
-             string_appends (tname, &temp);
-
-             if (!is_type)
-               {
-                 /* Save the template argument. */
-                 int len = temp.p - temp.b;
-                 work->tmpl_argvec[i] = xmalloc (len + 1);
-                 memcpy (work->tmpl_argvec[i], temp.b, len);
-                 work->tmpl_argvec[i][len] = '\0';
-               }
-           }
-         string_delete(&temp);
-         if (!success)
-           {
-             break;
-           }
-       }
-      /* z for template parameters */
-      else if (**mangled == 'z')
-       {
-         int r2;
-         (*mangled)++;
-         success = demangle_template_template_parm (work, mangled, tname);
-         
-         if (success
-             && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
-           {
-             string_append (tname, " ");
-             string_appendn (tname, *mangled, r2);
-             if (!is_type)
-               {
-                 /* Save the template argument. */
-                 int len = r2;
-                 work->tmpl_argvec[i] = xmalloc (len + 1);
-                 memcpy (work->tmpl_argvec[i], *mangled, len);
-                 work->tmpl_argvec[i][len] = '\0';
-               }
-             *mangled += r2;
-           }
-         if (!success)
-           {
-             break;
-           }
-       }
-      else
-       {
-         string  param;
-         string* s;
-         const char* start_of_value_parm = *mangled;
-
-         /* otherwise, value parameter */
-
-         /* temp is initialized in do_type */
-         success = do_type (work, mangled, &temp);
-         string_delete(&temp);
-         if (!success)
-           break;
-
-         if (!is_type)
-           {
-             s = &param;
-             string_init (s);
-           }
-         else
-           s = tname;
-
-         success = demangle_template_value_parm (work, mangled, s,
-                                                 (type_kind_t) success);
-
-         if (!success)
-           {
-             if (!is_type)
-               string_delete (s);
-             success = 0;
-             break;
-           }
-
-         if (!is_type)
-           {
-             int len = s->p - s->b;
-             work->tmpl_argvec[i] = xmalloc (len + 1);
-             memcpy (work->tmpl_argvec[i], s->b, len);
-             work->tmpl_argvec[i][len] = '\0';
-             
-             string_appends (tname, s);
-             string_delete (s);
-           }
-       }
-      need_comma = 1;
-    }
-    {
-  if (tname->p[-1] == '>')
-    string_append (tname, " ");
-  string_append (tname, ">");
-    }
-  
-  if (is_type && remember)
-    remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
-
-  /*
-    if (work -> static_type)
-    {
-    string_append (declp, *mangled + 1);
-    *mangled += strlen (*mangled);
-    success = 1;
-    }
-    else
-    {
-    success = demangle_args (work, mangled, declp);
-    }
-    }
-    */
-  return (success);
-}
-
-static int
-arm_pt (work, mangled, n, anchor, args)
-     struct work_stuff *work;
-     const char *mangled;
-     int n;
-     const char **anchor, **args;
-{
-  /* ARM template? */
-  if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
-    {
-      int len;
-      *args = *anchor + 6;
-      len = consume_count (args);
-      if (*args + len == mangled + n && **args == '_')
-       {
-         ++*args;
-         return 1;
-       }
-    }
-  return 0;
-}
-
-static void
-demangle_arm_pt (work, mangled, n, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     int n;
-     string *declp;
-{
-  const char *p;
-  const char *args;
-  const char *e = *mangled + n;
-
-  /* ARM template? */
-  if (arm_pt (work, *mangled, n, &p, &args))
-    {
-      string arg;
-      string_init (&arg);
-      string_appendn (declp, *mangled, p - *mangled);
-      string_append (declp, "<");
-      /* should do error checking here */
-      while (args < e) {
-       string_clear (&arg);
-       do_type (work, &args, &arg);
-       string_appends (declp, &arg);
-       string_append (declp, ",");
-      }
-      string_delete (&arg);
-      --declp->p;
-      string_append (declp, ">");
-    }
-  else
-    {
-      string_appendn (declp, *mangled, n);
-    }
-  *mangled += n;
-}
-
-static int
-demangle_class_name (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  int n;
-  int success = 0;
-
-  n = consume_count (mangled);
-  if (strlen (*mangled) >= n)
-    {
-      demangle_arm_pt (work, mangled, n, declp);
-      success = 1;
-    }
-
-  return (success);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       demangle_class -- demangle a mangled class sequence
-
-SYNOPSIS
-
-       static int
-       demangle_class (struct work_stuff *work, const char **mangled,
-                       strint *declp)
-
-DESCRIPTION
-
-       DECLP points to the buffer into which demangling is being done.
-
-       *MANGLED points to the current token to be demangled.  On input,
-       it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
-       On exit, it points to the next token after the mangled class on
-       success, or the first unconsumed token on failure.
-
-       If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
-       we are demangling a constructor or destructor.  In this case
-       we prepend "class::class" or "class::~class" to DECLP.
-
-       Otherwise, we prepend "class::" to the current DECLP.
-
-       Reset the constructor/destructor flags once they have been
-       "consumed".  This allows demangle_class to be called later during
-       the same demangling, to do normal class demangling.
-
-       Returns 1 if demangling is successful, 0 otherwise.
-
-*/
-
-static int
-demangle_class (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  int success = 0;
-  int btype;
-  string class_name;
-
-  string_init (&class_name);
-  btype = register_Btype (work);
-  if (demangle_class_name (work, mangled, &class_name))
-    {
-      if ((work->constructor & 1) || (work->destructor & 1))
-       {
-         string_prepends (declp, &class_name);
-         if (work -> destructor & 1)
-           {
-             string_prepend (declp, "~");
-              work -> destructor -= 1;
-           }
-         else
-           {
-             work -> constructor -= 1; 
-           }
-       }
-      remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
-      remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
-      string_prepend (declp, SCOPE_STRING (work));
-      string_prepends (declp, &class_name);
-      success = 1;
-    }
-  string_delete (&class_name);
-  return (success);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       demangle_prefix -- consume the mangled name prefix and find signature
-
-SYNOPSIS
-
-       static int
-       demangle_prefix (struct work_stuff *work, const char **mangled,
-                        string *declp);
-
-DESCRIPTION
-
-       Consume and demangle the prefix of the mangled name.
-
-       DECLP points to the string buffer into which demangled output is
-       placed.  On entry, the buffer is empty.  On exit it contains
-       the root function name, the demangled operator name, or in some
-       special cases either nothing or the completely demangled result.
-
-       MANGLED points to the current pointer into the mangled name.  As each
-       token of the mangled name is consumed, it is updated.  Upon entry
-       the current mangled name pointer points to the first character of
-       the mangled name.  Upon exit, it should point to the first character
-       of the signature if demangling was successful, or to the first
-       unconsumed character if demangling of the prefix was unsuccessful.
-       
-       Returns 1 on success, 0 otherwise.
- */
-
-static int
-demangle_prefix (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  int success = 1;
-  const char *scan;
-  int i;
-
-  if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
-    {
-      char *marker = strchr (cplus_markers, (*mangled)[8]);
-      if (marker != NULL && *marker == (*mangled)[10])
-       {
-         if ((*mangled)[9] == 'D')
-           {
-             /* it's a GNU global destructor to be executed at program exit */
-             (*mangled) += 11;
-             work->destructor = 2;
-             if (gnu_special (work, mangled, declp))
-               return success;
-           }
-         else if ((*mangled)[9] == 'I')
-           {
-             /* it's a GNU global constructor to be executed at program init */
-             (*mangled) += 11;
-             work->constructor = 2;
-             if (gnu_special (work, mangled, declp))
-               return success;
-           }
-       }
-    }
-  else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
-    {
-      /* it's a ARM global destructor to be executed at program exit */
-      (*mangled) += 7;
-      work->destructor = 2;
-    }
-  else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
-    {
-      /* it's a ARM global constructor to be executed at program initial */
-      (*mangled) += 7;
-      work->constructor = 2;
-    }
-
-  /*  This block of code is a reduction in strength time optimization
-      of:
-      scan = mystrstr (*mangled, "__"); */
-
-  {
-    scan = *mangled;
-
-    do {
-      scan = strchr (scan, '_');
-    } while (scan != NULL && *++scan != '_');
-
-    if (scan != NULL) --scan;
-  }
-
-  if (scan != NULL)
-    {
-      /* We found a sequence of two or more '_', ensure that we start at
-        the last pair in the sequence.  */
-      i = strspn (scan, "_");
-      if (i > 2)
-       {
-         scan += (i - 2); 
-       }
-    }
-  if (scan == NULL)
-    {
-      success = 0;
-    }
-  else if (work -> static_type)
-    {
-      if (!isdigit (scan[0]) && (scan[0] != 't'))
-       {
-         success = 0;
-       }
-    }
-  else if ((scan == *mangled)
-          && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
-              || (scan[2] == 'K') || (scan[2] == 'H')))
-    {
-      /* The ARM says nothing about the mangling of local variables.
-        But cfront mangles local variables by prepending __<nesting_level>
-        to them. As an extension to ARM demangling we handle this case.  */
-      if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
-       {
-         *mangled = scan + 2;
-         consume_count (mangled);
-         string_append (declp, *mangled);
-         *mangled += strlen (*mangled);
-         success = 1; 
-       }
-      else
-       {
-         /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
-            names like __Q2_3foo3bar for nested type names.  So don't accept
-            this style of constructor for cfront demangling.  A GNU
-            style member-template constructor starts with 'H'. */
-         if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
-           work -> constructor += 1;
-         *mangled = scan + 2;
-       }
-    }
-  else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
-    {
-      /* Mangled name starts with "__".  Skip over any leading '_' characters,
-        then find the next "__" that separates the prefix from the signature.
-        */
-      if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
-         || (arm_special (mangled, declp) == 0))
-       {
-         while (*scan == '_')
-           {
-             scan++;
-           }
-         if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
-           {
-             /* No separator (I.E. "__not_mangled"), or empty signature
-                (I.E. "__not_mangled_either__") */
-             success = 0;
-           }
-         else
-           {
-             demangle_function_name (work, mangled, declp, scan);
-           }
-       }
-    }
-  else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
-    {
-      /* Cfront-style parameterized type.  Handled later as a signature.  */
-      success = 1;
-
-      /* ARM template? */
-      demangle_arm_pt (work, mangled, strlen (*mangled), declp);
-    }
-  else if (*(scan + 2) != '\0')
-    {
-      /* Mangled name does not start with "__" but does have one somewhere
-        in there with non empty stuff after it.  Looks like a global
-        function name.  */
-      demangle_function_name (work, mangled, declp, scan);
-    }
-  else
-    {
-      /* Doesn't look like a mangled name */
-      success = 0;
-    }
-
-  if (!success && (work->constructor == 2 || work->destructor == 2))
-    {
-      string_append (declp, *mangled);
-      *mangled += strlen (*mangled);
-      success = 1;
-    } 
-  return (success);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       gnu_special -- special handling of gnu mangled strings
-
-SYNOPSIS
-
-       static int
-       gnu_special (struct work_stuff *work, const char **mangled,
-                    string *declp);
-
-
-DESCRIPTION
-
-       Process some special GNU style mangling forms that don't fit
-       the normal pattern.  For example:
-
-               _$_3foo         (destructor for class foo)
-               _vt$foo         (foo virtual table)
-               _vt$foo$bar     (foo::bar virtual table)
-               __vt_foo        (foo virtual table, new style with thunks)
-               _3foo$varname   (static data member)
-               _Q22rs2tu$vw    (static data member)
-               __t6vector1Zii  (constructor with template)
-               __thunk_4__$_7ostream (virtual function thunk)
- */
-
-static int
-gnu_special (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  int n;
-  int success = 1;
-  const char *p;
-
-  if ((*mangled)[0] == '_'
-      && strchr (cplus_markers, (*mangled)[1]) != NULL
-      && (*mangled)[2] == '_')
-    {
-      /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
-      (*mangled) += 3;
-      work -> destructor += 1;
-    }
-  else if ((*mangled)[0] == '_'
-          && (((*mangled)[1] == '_'
-               && (*mangled)[2] == 'v'
-               && (*mangled)[3] == 't'
-               && (*mangled)[4] == '_')
-              || ((*mangled)[1] == 'v'
-                  && (*mangled)[2] == 't'
-                  && strchr (cplus_markers, (*mangled)[3]) != NULL)))
-    {
-      /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
-         and create the decl.  Note that we consume the entire mangled
-        input string, which means that demangle_signature has no work
-        to do.  */
-      if ((*mangled)[2] == 'v')
-       (*mangled) += 5; /* New style, with thunks: "__vt_" */
-      else
-       (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
-      while (**mangled != '\0')
-       {
-         p = strpbrk (*mangled, cplus_markers);
-         switch (**mangled)
-           {
-           case 'Q':
-           case 'K':
-             success = demangle_qualified (work, mangled, declp, 0, 1);
-             break;
-           case 't':
-             success = demangle_template (work, mangled, declp, 0, 1,
-                                          1);
-             break;
-           default:
-             if (isdigit(*mangled[0]))
-               {
-                 n = consume_count(mangled);
-                 /* We may be seeing a too-large size, or else a
-                    ".<digits>" indicating a static local symbol.  In
-                    any case, declare victory and move on; *don't* try
-                    to use n to allocate.  */
-                 if (n > strlen (*mangled))
-                   {
-                     success = 1;
-                     break;
-                   }
-               }
-             else
-               {
-                 n = strcspn (*mangled, cplus_markers);
-               }
-             string_appendn (declp, *mangled, n);
-             (*mangled) += n;
-           }
-
-         if (success && ((p == NULL) || (p == *mangled)))
-           {
-             if (p != NULL)
-               {
-                 string_append (declp, SCOPE_STRING (work));
-                 (*mangled)++;
-               }
-           }
-         else
-           {
-             success = 0;
-             break;
-           }
-       }
-      if (success)
-       string_append (declp, " virtual table");
-    }
-  else if ((*mangled)[0] == '_'
-          && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
-          && (p = strpbrk (*mangled, cplus_markers)) != NULL)
-    {
-      /* static data member, "_3foo$varname" for example */
-      (*mangled)++;
-      switch (**mangled)
-       {
-       case 'Q':
-       case 'K':
-         success = demangle_qualified (work, mangled, declp, 0, 1);
-         break;
-       case 't':
-         success = demangle_template (work, mangled, declp, 0, 1, 1);
-         break;
-       default:
-         n = consume_count (mangled);
-         string_appendn (declp, *mangled, n);
-         (*mangled) += n;
-       }
-      if (success && (p == *mangled))
-       {
-         /* Consumed everything up to the cplus_marker, append the
-            variable name.  */
-         (*mangled)++;
-         string_append (declp, SCOPE_STRING (work));
-         n = strlen (*mangled);
-         string_appendn (declp, *mangled, n);
-         (*mangled) += n;
-       }
-      else
-       {
-         success = 0;
-       }
-    }
-  else if (strncmp (*mangled, "__thunk_", 8) == 0)
-    {
-      int delta = ((*mangled) += 8, consume_count (mangled));
-      char *method = internal_cplus_demangle (work, ++*mangled);
-      if (method)
-       {
-         char buf[50];
-         sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
-         string_append (declp, buf);
-         string_append (declp, method);
-         free (method);
-         n = strlen (*mangled);
-         (*mangled) += n;
-       }
-      else
-       {
-         success = 0;
-       }
-    }
-  else if (strncmp (*mangled, "__t", 3) == 0
-          && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
-    {
-      p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
-      (*mangled) += 4;
-      switch (**mangled)
-       {
-       case 'Q':
-       case 'K':
-         success = demangle_qualified (work, mangled, declp, 0, 1);
-         break;
-       case 't':
-         success = demangle_template (work, mangled, declp, 0, 1, 1);
-         break;
-       default:
-         success = demangle_fund_type (work, mangled, declp);
-         break;
-       }
-      if (success && **mangled != '\0')
-       success = 0;
-      if (success)
-       string_append (declp, p);
-    }
-  else
-    {
-      success = 0;
-    }
-  return (success);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       arm_special -- special handling of ARM/lucid mangled strings
-
-SYNOPSIS
-
-       static int
-       arm_special (const char **mangled,
-                    string *declp);
-
-
-DESCRIPTION
-
-       Process some special ARM style mangling forms that don't fit
-       the normal pattern.  For example:
-
-               __vtbl__3foo            (foo virtual table)
-               __vtbl__3foo__3bar      (bar::foo virtual table)
-
- */
-
-static int
-arm_special (mangled, declp)
-     const char **mangled;
-     string *declp;
-{
-  int n;
-  int success = 1;
-  const char *scan;
-
-  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
-    {
-      /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
-         and create the decl.  Note that we consume the entire mangled
-        input string, which means that demangle_signature has no work
-        to do.  */
-      scan = *mangled + ARM_VTABLE_STRLEN;
-      while (*scan != '\0')        /* first check it can be demangled */
-        {
-          n = consume_count (&scan);
-          if (n==0)
-           {
-             return (0);           /* no good */
-           }
-          scan += n;
-          if (scan[0] == '_' && scan[1] == '_')
-           {
-             scan += 2;
-           }
-        }
-      (*mangled) += ARM_VTABLE_STRLEN;
-      while (**mangled != '\0')
-       {
-         n = consume_count (mangled);
-         string_prependn (declp, *mangled, n);
-         (*mangled) += n;
-         if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
-           {
-             string_prepend (declp, "::");
-             (*mangled) += 2;
-           }
-       }
-      string_append (declp, " virtual table");
-    }
-  else
-    {
-      success = 0;
-    }
-  return (success);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       demangle_qualified -- demangle 'Q' qualified name strings
-
-SYNOPSIS
-
-       static int
-       demangle_qualified (struct work_stuff *, const char *mangled,
-                           string *result, int isfuncname, int append);
-
-DESCRIPTION
-
-       Demangle a qualified name, such as "Q25Outer5Inner" which is
-       the mangled form of "Outer::Inner".  The demangled output is
-       prepended or appended to the result string according to the
-       state of the append flag.
-
-       If isfuncname is nonzero, then the qualified name we are building
-       is going to be used as a member function name, so if it is a
-       constructor or destructor function, append an appropriate
-       constructor or destructor name.  I.E. for the above example,
-       the result for use as a constructor is "Outer::Inner::Inner"
-       and the result for use as a destructor is "Outer::Inner::~Inner".
-
-BUGS
-
-       Numeric conversion is ASCII dependent (FIXME).
-
- */
-
-static int
-demangle_qualified (work, mangled, result, isfuncname, append)
-     struct work_stuff *work;
-     const char **mangled;
-     string *result;
-     int isfuncname;
-     int append;
-{
-  int qualifiers = 0;
-  int success = 1;
-  const char *p;
-  char num[2];
-  string temp;
-  string last_name;
-  int bindex = register_Btype (work);
-
-  /* We only make use of ISFUNCNAME if the entity is a constructor or
-     destructor.  */
-  isfuncname = (isfuncname 
-               && ((work->constructor & 1) || (work->destructor & 1)));
-
-  string_init (&temp);
-  string_init (&last_name);
-
-  if ((*mangled)[0] == 'K')
-    {
-    /* Squangling qualified name reuse */
-      int idx;
-      (*mangled)++;
-      idx = consume_count_with_underscores (mangled);
-      if (idx == -1 || idx > work -> numk)
-        success = 0;
-      else
-        string_append (&temp, work -> ktypevec[idx]);
-    }
-  else
-    switch ((*mangled)[1])
-    {
-    case '_':
-      /* GNU mangled name with more than 9 classes.  The count is preceded
-        by an underscore (to distinguish it from the <= 9 case) and followed
-        by an underscore.  */
-      p = *mangled + 2;
-      qualifiers = atoi (p);
-      if (!isdigit (*p) || *p == '0')
-       success = 0;
-
-      /* Skip the digits.  */
-      while (isdigit (*p))
-       ++p;
-
-      if (*p != '_')
-       success = 0;
-
-      *mangled = p + 1;
-      break;
-
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      /* The count is in a single digit.  */
-      num[0] = (*mangled)[1];
-      num[1] = '\0';
-      qualifiers = atoi (num);
-
-      /* If there is an underscore after the digit, skip it.  This is
-        said to be for ARM-qualified names, but the ARM makes no
-        mention of such an underscore.  Perhaps cfront uses one.  */
-      if ((*mangled)[2] == '_')
-       {
-         (*mangled)++;
-       }
-      (*mangled) += 2;
-      break;
-
-    case '0':
-    default:
-      success = 0;
-    }
-
-  if (!success)
-    return success;
-
-  /* Pick off the names and collect them in the temp buffer in the order
-     in which they are found, separated by '::'.  */
-
-  while (qualifiers-- > 0)
-    {
-      int remember_K = 1;
-      string_clear (&last_name);
-
-      if (*mangled[0] == '_') 
-       (*mangled)++;
-
-      if (*mangled[0] == 't')
-       {
-         /* Here we always append to TEMP since we will want to use
-            the template name without the template parameters as a
-            constructor or destructor name.  The appropriate
-            (parameter-less) value is returned by demangle_template
-            in LAST_NAME.  We do not remember the template type here,
-            in order to match the G++ mangling algorithm.  */
-         success = demangle_template(work, mangled, &temp, 
-                                     &last_name, 1, 0);
-         if (!success) 
-           break;
-       } 
-      else if (*mangled[0] == 'K')
-       {
-          int idx;
-          (*mangled)++;
-          idx = consume_count_with_underscores (mangled);
-          if (idx == -1 || idx > work->numk)
-            success = 0;
-          else
-            string_append (&temp, work->ktypevec[idx]);
-          remember_K = 0;
-
-         if (!success) break;
-       }
-      else
-       {
-         success = do_type (work, mangled, &last_name);
-         if (!success)
-           break;
-         string_appends (&temp, &last_name);
-       }
-
-      if (remember_K)
-       remember_Ktype (work, temp.b, LEN_STRING (&temp));
-
-      if (qualifiers > 0)
-       string_append (&temp, SCOPE_STRING (work));
-    }
-
-  remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
-
-  /* If we are using the result as a function name, we need to append
-     the appropriate '::' separated constructor or destructor name.
-     We do this here because this is the most convenient place, where
-     we already have a pointer to the name and the length of the name.  */
-
-  if (isfuncname) 
-    {
-      string_append (&temp, SCOPE_STRING (work));
-      if (work -> destructor & 1)
-       string_append (&temp, "~");
-      string_appends (&temp, &last_name);
-    }
-
-  /* Now either prepend the temp buffer to the result, or append it, 
-     depending upon the state of the append flag.  */
-
-  if (append)
-    string_appends (result, &temp);
-  else
-    {
-      if (!STRING_EMPTY (result))
-       string_append (&temp, SCOPE_STRING (work));
-      string_prepends (result, &temp);
-    }
-
-  string_delete (&last_name);
-  string_delete (&temp);
-  return (success);
-}
-
-/*
-
-LOCAL FUNCTION
-
-       get_count -- convert an ascii count to integer, consuming tokens
-
-SYNOPSIS
-
-       static int
-       get_count (const char **type, int *count)
-
-DESCRIPTION
-
-       Return 0 if no conversion is performed, 1 if a string is converted.
-*/
-
-static int
-get_count (type, count)
-     const char **type;
-     int *count;
-{
-  const char *p;
-  int n;
-
-  if (!isdigit (**type))
-    {
-      return (0);
-    }
-  else
-    {
-      *count = **type - '0';
-      (*type)++;
-      if (isdigit (**type))
-       {
-         p = *type;
-         n = *count;
-         do 
-           {
-             n *= 10;
-             n += *p - '0';
-             p++;
-           } 
-         while (isdigit (*p));
-         if (*p == '_')
-           {
-             *type = p + 1;
-             *count = n;
-           }
-       }
-    }
-  return (1);
-}
-
-/* RESULT will be initialised here; it will be freed on failure.  The
-   value returned is really a type_kind_t.  */
-
-static int
-do_type (work, mangled, result)
-     struct work_stuff *work;
-     const char **mangled;
-     string *result;
-{
-  int n;
-  int done;
-  int success;
-  string decl;
-  const char *remembered_type;
-  int constp;
-  int volatilep;
-  string btype;
-  type_kind_t tk = tk_none;
-
-  string_init (&btype);
-  string_init (&decl);
-  string_init (result);
-
-  done = 0;
-  success = 1;
-  while (success && !done)
-    {
-      int member;
-      switch (**mangled)
-       {
-
-         /* A pointer type */
-       case 'P':
-       case 'p':
-         (*mangled)++;
-         string_prepend (&decl, "*");
-         if (tk == tk_none)
-           tk = tk_pointer;
-         break;
-
-         /* A reference type */
-       case 'R':
-         (*mangled)++;
-         string_prepend (&decl, "&");
-         if (tk == tk_none)
-           tk = tk_pointer;
-         break;
-
-         /* An array */
-       case 'A':
-         {
-           ++(*mangled);
-           string_prepend (&decl, "(");
-           string_append (&decl, ")[");
-           success = demangle_template_value_parm (work, mangled, &decl,
-                                                   tk_integral);
-           if (**mangled == '_')
-             ++(*mangled);
-           string_append (&decl, "]");
-           break;
-         }
-
-       /* A back reference to a previously seen type */
-       case 'T':
-         (*mangled)++;
-         if (!get_count (mangled, &n) || n >= work -> ntypes)
-           {
-             success = 0;
-           }
-         else
-           {
-             remembered_type = work -> typevec[n];
-             mangled = &remembered_type;
-           }
-         break;
-
-         /* A function */
-       case 'F':
-         (*mangled)++;
-         if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
-           {
-             string_prepend (&decl, "(");
-             string_append (&decl, ")");
-           }
-         /* After picking off the function args, we expect to either find the
-            function return type (preceded by an '_') or the end of the
-            string.  */
-         if (!demangle_nested_args (work, mangled, &decl)
-             || (**mangled != '_' && **mangled != '\0'))
-           {
-             success = 0;
-             break;
-           }
-         if (success && (**mangled == '_'))
-           (*mangled)++;
-         break;
-
-       case 'M':
-       case 'O':
-         {
-           constp = 0;
-           volatilep = 0;
-
-           member = **mangled == 'M';
-           (*mangled)++;
-           if (!isdigit (**mangled) && **mangled != 't')
-             {
-               success = 0;
-               break;
-             }
-
-           string_append (&decl, ")");
-           string_prepend (&decl, SCOPE_STRING (work));
-           if (isdigit (**mangled)) 
-             {
-               n = consume_count (mangled);
-               if (strlen (*mangled) < n)
-                 {
-                   success = 0;
-                   break;
-                 }
-               string_prependn (&decl, *mangled, n);
-               *mangled += n;
-             }
-           else
-             {
-               string temp;
-               string_init (&temp);
-               success = demangle_template (work, mangled, &temp,
-                                            NULL, 1, 1);
-               if (success)
-                 {
-                   string_prependn (&decl, temp.b, temp.p - temp.b);
-                   string_clear (&temp);
-                 }
-               else
-                 break;
-             }
-           string_prepend (&decl, "(");
-           if (member)
-             {
-               if (**mangled == 'C')
-                 {
-                   (*mangled)++;
-                   constp = 1;
-                 }
-               if (**mangled == 'V')
-                 {
-                   (*mangled)++;
-                   volatilep = 1;
-                 }
-               if (*(*mangled)++ != 'F')
-                 {
-                   success = 0;
-                   break;
-                 }
-             }
-           if ((member && !demangle_nested_args (work, mangled, &decl))
-               || **mangled != '_')
-             {
-               success = 0;
-               break;
-             }
-           (*mangled)++;
-           if (! PRINT_ANSI_QUALIFIERS)
-             {
-               break;
-             }
-           if (constp)
-             {
-               APPEND_BLANK (&decl);
-               string_append (&decl, "const");
-             }
-           if (volatilep)
-             {
-               APPEND_BLANK (&decl);
-               string_append (&decl, "volatile");
-             }
-           break;
-         }
-        case 'G':
-         (*mangled)++;
-         break;
-
-       case 'C':
-       case 'V':
-         /*
-           if ((*mangled)[1] == 'P')
-           {
-           */
-         if (PRINT_ANSI_QUALIFIERS)
-           {
-             if (!STRING_EMPTY (&decl))
-               {
-                 string_prepend (&decl, " ");
-               }
-             string_prepend (&decl, 
-                             (**mangled) == 'C' ? "const" : "volatile");
-           }
-         (*mangled)++;
-         break;
-         /*
-           }
-           */
-
-         /* fall through */
-       default:
-         done = 1;
-         break;
-       }
-    }
-
-  switch (**mangled)
-    {
-      /* A qualified name, such as "Outer::Inner".  */
-    case 'Q':
-    case 'K':
-      {
-        success = demangle_qualified (work, mangled, result, 0, 1);
-        break;
-      }
-
-    /* A back reference to a previously seen squangled type */
-    case 'B':
-      (*mangled)++;
-      if (!get_count (mangled, &n) || n >= work -> numb)
-          success = 0;
-      else
-       string_append (result, work->btypevec[n]);
-      break;
-
-    case 'X':
-    case 'Y':
-      /* A template parm.  We substitute the corresponding argument. */
-      {
-       int idx;
-
-       (*mangled)++;
-       idx = consume_count_with_underscores (mangled);
-
-       if (idx == -1 
-           || (work->tmpl_argvec && idx >= work->ntmpl_args)
-           || consume_count_with_underscores (mangled) == -1)
-         {
-           success = 0;
-           break;
-         }
-
-       if (work->tmpl_argvec)
-         string_append (result, work->tmpl_argvec[idx]);
-       else
-         {
-           char buf[10];
-           sprintf(buf, "T%d", idx);
-           string_append (result, buf);
-         }
-
-       success = 1;
-      }
-    break;
-
-    default:
-      success = demangle_fund_type (work, mangled, result);
-      if (tk == tk_none)
-       tk = (type_kind_t) success;
-      break;
-    }
-
-  if (success)
-    {
-      if (!STRING_EMPTY (&decl))
-       {
-         string_append (result, " ");
-         string_appends (result, &decl);
-       }
-    }
-  else
-    string_delete (result);
-  string_delete (&decl);
-
-  if (success)
-    /* Assume an integral type, if we're not sure.  */
-    return (int) ((tk == tk_none) ? tk_integral : tk);
-  else
-    return 0;
-}
-
-/* Given a pointer to a type string that represents a fundamental type
-   argument (int, long, unsigned int, etc) in TYPE, a pointer to the
-   string in which the demangled output is being built in RESULT, and
-   the WORK structure, decode the types and add them to the result.
-
-   For example:
-
-       "Ci"    =>      "const int"
-       "Sl"    =>      "signed long"
-       "CUs"   =>      "const unsigned short"
-
-   The value returned is really a type_kind_t.  */
-
-static int
-demangle_fund_type (work, mangled, result)
-     struct work_stuff *work;
-     const char **mangled;
-     string *result;
-{
-  int done = 0;
-  int success = 1;
-  string btype;
-  type_kind_t tk = tk_integral;
-
-  string_init (&btype);
-
-  /* First pick off any type qualifiers.  There can be more than one.  */
-
-  while (!done)
-    {
-      switch (**mangled)
-       {
-       case 'C':
-         (*mangled)++;
-         if (PRINT_ANSI_QUALIFIERS)
-           {
-             APPEND_BLANK (result);
-             string_append (result, "const");
-           }
-         break;
-       case 'U':
-         (*mangled)++;
-         APPEND_BLANK (result);
-         string_append (result, "unsigned");
-         break;
-       case 'S': /* signed char only */
-         (*mangled)++;
-         APPEND_BLANK (result);
-         string_append (result, "signed");
-         break;
-       case 'V':
-         (*mangled)++;
-         if (PRINT_ANSI_QUALIFIERS)
-           {
-             APPEND_BLANK (result);
-             string_append (result, "volatile");
-           }
-         break;
-       case 'J':
-         (*mangled)++;
-         APPEND_BLANK (result);
-         string_append (result, "__complex");
-         break;
-       default:
-         done = 1;
-         break;
-       }
-    }
-
-  /* Now pick off the fundamental type.  There can be only one.  */
-
-  switch (**mangled)
-    {
-    case '\0':
-    case '_':
-      break;
-    case 'v':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "void");
-      break;
-    case 'x':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "long long");
-      break;
-    case 'l':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "long");
-      break;
-    case 'i':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "int");
-      break;
-    case 's':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "short");
-      break;
-    case 'b':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "bool");
-      tk = tk_bool;
-      break;
-    case 'c':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "char");
-      tk = tk_char;
-      break;
-    case 'w':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "wchar_t");
-      tk = tk_char;
-      break;
-    case 'r':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "long double");
-      tk = tk_real;
-      break;
-    case 'd':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "double");
-      tk = tk_real;
-      break;
-    case 'f':
-      (*mangled)++;
-      APPEND_BLANK (result);
-      string_append (result, "float");
-      tk = tk_real;
-      break;
-    case 'G':
-      (*mangled)++;
-      if (!isdigit (**mangled))
-       {
-         success = 0;
-         break;
-       }
-      /* fall through */
-      /* An explicit type, such as "6mytype" or "7integer" */
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      {
-        int bindex = register_Btype (work);
-        string btype;
-        string_init (&btype);
-        if (demangle_class_name (work, mangled, &btype)) {
-          remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
-          APPEND_BLANK (result);
-          string_appends (result, &btype);
-        }
-        else 
-          success = 0;
-        string_delete (&btype);
-        break;
-      }
-    case 't':
-      {
-        success = demangle_template (work, mangled, &btype, 0, 1, 1);
-        string_appends (result, &btype);
-        break;
-      }
-    default:
-      success = 0;
-      break;
-    }
-
-  return success ? ((int) tk) : 0;
-}
-
-/* Demangle the next argument, given by MANGLED into RESULT, which
-   *should be an uninitialized* string.  It will be initialized here,
-   and free'd should anything go wrong.  */
-
-static int
-do_arg (work, mangled, result)
-     struct work_stuff *work;
-     const char **mangled;
-     string *result;
-{
-  /* Remember where we started so that we can record the type, for
-     non-squangling type remembering.  */
-  const char *start = *mangled;
-
-  string_init (result);
-
-  if (work->nrepeats > 0)
-    {
-      --work->nrepeats;
-
-      if (work->previous_argument == 0)
-       return 0;
-
-      /* We want to reissue the previous type in this argument list.  */ 
-      string_appends (result, work->previous_argument);
-      return 1;
-    }
-
-  if (**mangled == 'n')
-    {
-      /* A squangling-style repeat.  */
-      (*mangled)++;
-      work->nrepeats = consume_count(mangled);
-
-      if (work->nrepeats == 0)
-       /* This was not a repeat count after all.  */
-       return 0;
-
-      if (work->nrepeats > 9)
-       {
-         if (**mangled != '_')
-           /* The repeat count should be followed by an '_' in this
-              case.  */
-           return 0;
-         else
-           (*mangled)++;
-       }
-      
-      /* Now, the repeat is all set up.  */
-      return do_arg (work, mangled, result);
-    }
-
-  /* Save the result in WORK->previous_argument so that we can find it
-     if it's repeated.  Note that saving START is not good enough: we
-     do not want to add additional types to the back-referenceable
-     type vector when processing a repeated type.  */
-  if (work->previous_argument)
-    string_clear (work->previous_argument);
-  else
-    {
-      work->previous_argument = (string*) xmalloc (sizeof (string));
-      string_init (work->previous_argument);
-    }
-
-  if (!do_type (work, mangled, work->previous_argument))
-    return 0;
-
-  string_appends (result, work->previous_argument);
-
-  remember_type (work, start, *mangled - start);
-  return 1;
-}
-
-static void
-remember_type (work, start, len)
-     struct work_stuff *work;
-     const char *start;
-     int len;
-{
-  char *tem;
-
-  if (work->forgetting_types)
-    return;
-
-  if (work -> ntypes >= work -> typevec_size)
-    {
-      if (work -> typevec_size == 0)
-       {
-         work -> typevec_size = 3;
-         work -> typevec
-           = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
-       }
-      else
-       {
-         work -> typevec_size *= 2;
-         work -> typevec
-           = (char **) xrealloc ((char *)work -> typevec,
-                                 sizeof (char *) * work -> typevec_size);
-       }
-    }
-  tem = xmalloc (len + 1);
-  memcpy (tem, start, len);
-  tem[len] = '\0';
-  work -> typevec[work -> ntypes++] = tem;
-}
-
-
-/* Remember a K type class qualifier. */
-static void
-remember_Ktype (work, start, len)
-     struct work_stuff *work;
-     const char *start;
-     int len;
-{
-  char *tem;
-
-  if (work -> numk >= work -> ksize)
-    {
-      if (work -> ksize == 0)
-       {
-         work -> ksize = 5;
-         work -> ktypevec
-           = (char **) xmalloc (sizeof (char *) * work -> ksize);
-       }
-      else
-       {
-         work -> ksize *= 2;
-         work -> ktypevec
-           = (char **) xrealloc ((char *)work -> ktypevec,
-                                 sizeof (char *) * work -> ksize);
-       }
-    }
-  tem = xmalloc (len + 1);
-  memcpy (tem, start, len);
-  tem[len] = '\0';
-  work -> ktypevec[work -> numk++] = tem;
-}
-
-/* Register a B code, and get an index for it. B codes are registered
-   as they are seen, rather than as they are completed, so map<temp<char> >  
-   registers map<temp<char> > as B0, and temp<char> as B1 */
-
-static int
-register_Btype (work)
-     struct work_stuff *work;
-{
-  int ret;
-  if (work -> numb >= work -> bsize)
-    {
-      if (work -> bsize == 0)
-       {
-         work -> bsize = 5;
-         work -> btypevec
-           = (char **) xmalloc (sizeof (char *) * work -> bsize);
-       }
-      else
-       {
-         work -> bsize *= 2;
-         work -> btypevec
-           = (char **) xrealloc ((char *)work -> btypevec,
-                                 sizeof (char *) * work -> bsize);
-       }
-    }
-  ret = work -> numb++;
-  work -> btypevec[ret] = NULL;
-  return(ret);
-}
-
-/* Store a value into a previously registered B code type. */
-
-static void
-remember_Btype (work, start, len, index)
-     struct work_stuff *work;
-     const char *start;
-     int len, index;
-{
-  char *tem;
-
-  tem = xmalloc (len + 1);
-  memcpy (tem, start, len);
-  tem[len] = '\0';
-  work -> btypevec[index] = tem;
-}
-
-/* Lose all the info related to B and K type codes. */
-static void
-forget_B_and_K_types (work)
-     struct work_stuff *work;
-{
-  int i;
-
-  while (work -> numk > 0)
-    {
-      i = --(work -> numk);
-      if (work -> ktypevec[i] != NULL)
-       {
-         free (work -> ktypevec[i]);
-         work -> ktypevec[i] = NULL;
-       }
-    }
-
-  while (work -> numb > 0)
-    {
-      i = --(work -> numb);
-      if (work -> btypevec[i] != NULL)
-       {
-         free (work -> btypevec[i]);
-         work -> btypevec[i] = NULL;
-       }
-    }
-}
-/* Forget the remembered types, but not the type vector itself.  */
-
-static void
-forget_types (work)
-     struct work_stuff *work;
-{
-  int i;
-
-  while (work -> ntypes > 0)
-    {
-      i = --(work -> ntypes);
-      if (work -> typevec[i] != NULL)
-       {
-         free (work -> typevec[i]);
-         work -> typevec[i] = NULL;
-       }
-    }
-}
-
-/* Process the argument list part of the signature, after any class spec
-   has been consumed, as well as the first 'F' character (if any).  For
-   example:
-
-   "__als__3fooRT0"            =>      process "RT0"
-   "complexfunc5__FPFPc_PFl_i" =>      process "PFPc_PFl_i"
-
-   DECLP must be already initialised, usually non-empty.  It won't be freed
-   on failure.
-
-   Note that g++ differs significantly from ARM and lucid style mangling
-   with regards to references to previously seen types.  For example, given
-   the source fragment:
-
-     class foo {
-       public:
-       foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
-     };
-
-     foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
-     void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
-
-   g++ produces the names:
-
-     __3fooiRT0iT2iT2
-     foo__FiR3fooiT1iT1
-
-   while lcc (and presumably other ARM style compilers as well) produces:
-
-     foo__FiR3fooT1T2T1T2
-     __ct__3fooFiR3fooT1T2T1T2
-
-   Note that g++ bases its type numbers starting at zero and counts all
-   previously seen types, while lucid/ARM bases its type numbers starting
-   at one and only considers types after it has seen the 'F' character
-   indicating the start of the function args.  For lucid/ARM style, we
-   account for this difference by discarding any previously seen types when
-   we see the 'F' character, and subtracting one from the type number
-   reference.
-
- */
-
-static int
-demangle_args (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  string arg;
-  int need_comma = 0;
-  int r;
-  int t;
-  const char *tem;
-  char temptype;
-
-  if (PRINT_ARG_TYPES)
-    {
-      string_append (declp, "(");
-      if (**mangled == '\0')
-       {
-         string_append (declp, "void");
-       }
-    }
-
-  while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
-        || work->nrepeats > 0)
-    {
-      if ((**mangled == 'N') || (**mangled == 'T'))
-       {
-         temptype = *(*mangled)++;
-         
-         if (temptype == 'N')
-           {
-             if (!get_count (mangled, &r))
-               {
-                 return (0);
-               }
-           }
-         else
-           {
-             r = 1;
-           }
-          if (ARM_DEMANGLING && work -> ntypes >= 10)
-            {
-              /* If we have 10 or more types we might have more than a 1 digit
-                 index so we'll have to consume the whole count here. This
-                 will lose if the next thing is a type name preceded by a
-                 count but it's impossible to demangle that case properly
-                 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
-                 Pc, ...)"  or "(..., type12, char *, ...)" */
-              if ((t = consume_count(mangled)) == 0)
-                {
-                  return (0);
-                }
-            }
-          else
-           {
-             if (!get_count (mangled, &t))
-               {
-                 return (0);
-               }
-           }
-         if (LUCID_DEMANGLING || ARM_DEMANGLING)
-           {
-             t--;
-           }
-         /* Validate the type index.  Protect against illegal indices from
-            malformed type strings.  */
-         if ((t < 0) || (t >= work -> ntypes))
-           {
-             return (0);
-           }
-         while (work->nrepeats > 0 || --r >= 0)
-           {
-             tem = work -> typevec[t];
-             if (need_comma && PRINT_ARG_TYPES)
-               {
-                 string_append (declp, ", ");
-               }
-             if (!do_arg (work, &tem, &arg))
-               {
-                 return (0);
-               }
-             if (PRINT_ARG_TYPES)
-               {
-                 string_appends (declp, &arg);
-               }
-             string_delete (&arg);
-             need_comma = 1;
-           }
-       }
-      else
-       {
-         if (need_comma && PRINT_ARG_TYPES)
-           string_append (declp, ", ");
-         if (!do_arg (work, mangled, &arg))
-           return (0);
-         if (PRINT_ARG_TYPES)
-           string_appends (declp, &arg);
-         string_delete (&arg);
-         need_comma = 1;
-       }
-    }
-
-  if (**mangled == 'e')
-    {
-      (*mangled)++;
-      if (PRINT_ARG_TYPES)
-       {
-         if (need_comma)
-           {
-             string_append (declp, ",");
-           }
-         string_append (declp, "...");
-       }
-    }
-
-  if (PRINT_ARG_TYPES)
-    {
-      string_append (declp, ")");
-    }
-  return (1);
-}
-
-/* Like demangle_args, but for demangling the argument lists of function
-   and method pointers or references, not top-level declarations.  */
-
-static int
-demangle_nested_args (work, mangled, declp)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-{
-  string* saved_previous_argument;
-  int result;
-  int saved_nrepeats;
-
-  /* The G++ name-mangling algorithm does not remember types on nested
-     argument lists, unless -fsquangling is used, and in that case the
-     type vector updated by remember_type is not used.  So, we turn
-     off remembering of types here.  */
-  ++work->forgetting_types;
-
-  /* For the repeat codes used with -fsquangling, we must keep track of
-     the last argument.  */
-  saved_previous_argument = work->previous_argument;
-  saved_nrepeats = work->nrepeats;
-  work->previous_argument = 0;
-  work->nrepeats = 0;
-
-  /* Actually demangle the arguments.  */
-  result = demangle_args (work, mangled, declp);
-  
-  /* Restore the previous_argument field.  */
-  if (work->previous_argument)
-    string_delete (work->previous_argument);
-  work->previous_argument = saved_previous_argument;
-  work->nrepeats = saved_nrepeats;
-
-  return result;
-}
-
-static void
-demangle_function_name (work, mangled, declp, scan)
-     struct work_stuff *work;
-     const char **mangled;
-     string *declp;
-     const char *scan;
-{
-  size_t i;
-  string type;
-  const char *tem;
-
-  string_appendn (declp, (*mangled), scan - (*mangled));
-  string_need (declp, 1);
-  *(declp -> p) = '\0';
-
-  /* Consume the function name, including the "__" separating the name
-     from the signature.  We are guaranteed that SCAN points to the
-     separator.  */
-
-  (*mangled) = scan + 2;
-
-  if (LUCID_DEMANGLING || ARM_DEMANGLING)
-    {
-
-      /* See if we have an ARM style constructor or destructor operator.
-        If so, then just record it, clear the decl, and return.
-        We can't build the actual constructor/destructor decl until later,
-        when we recover the class name from the signature.  */
-
-      if (strcmp (declp -> b, "__ct") == 0)
-       {
-         work -> constructor += 1;
-         string_clear (declp);
-         return;
-       }
-      else if (strcmp (declp -> b, "__dt") == 0)
-       {
-         work -> destructor += 1;
-         string_clear (declp);
-         return;
-       }
-    }
-
-  if (declp->p - declp->b >= 3 
-      && declp->b[0] == 'o'
-      && declp->b[1] == 'p'
-      && strchr (cplus_markers, declp->b[2]) != NULL)
-    {
-      /* see if it's an assignment expression */
-      if (declp->p - declp->b >= 10 /* op$assign_ */
-         && memcmp (declp->b + 3, "assign_", 7) == 0)
-       {
-         for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-           {
-             int len = declp->p - declp->b - 10;
-             if (strlen (optable[i].in) == len
-                 && memcmp (optable[i].in, declp->b + 10, len) == 0)
-               {
-                 string_clear (declp);
-                 string_append (declp, "operator");
-                 string_append (declp, optable[i].out);
-                 string_append (declp, "=");
-                 break;
-               }
-           }
-       }
-      else
-       {
-         for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-           {
-             int len = declp->p - declp->b - 3;
-             if (strlen (optable[i].in) == len 
-                 && memcmp (optable[i].in, declp->b + 3, len) == 0)
-               {
-                 string_clear (declp);
-                 string_append (declp, "operator");
-                 string_append (declp, optable[i].out);
-                 break;
-               }
-           }
-       }
-    }
-  else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
-          && strchr (cplus_markers, declp->b[4]) != NULL)
-    {
-      /* type conversion operator */
-      tem = declp->b + 5;
-      if (do_type (work, &tem, &type))
-       {
-         string_clear (declp);
-         string_append (declp, "operator ");
-         string_appends (declp, &type);
-         string_delete (&type);
-       }
-    }
-  else if (declp->b[0] == '_' && declp->b[1] == '_'
-          && declp->b[2] == 'o' && declp->b[3] == 'p')
-    {
-      /* ANSI.  */
-      /* type conversion operator.  */
-      tem = declp->b + 4;
-      if (do_type (work, &tem, &type))
-       {
-         string_clear (declp);
-         string_append (declp, "operator ");
-         string_appends (declp, &type);
-         string_delete (&type);
-       }
-    }
-  else if (declp->b[0] == '_' && declp->b[1] == '_'
-          && declp->b[2] >= 'a' && declp->b[2] <= 'z'
-          && declp->b[3] >= 'a' && declp->b[3] <= 'z')
-    {
-      if (declp->b[4] == '\0')
-       {
-         /* Operator.  */
-         for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-           {
-             if (strlen (optable[i].in) == 2
-                 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
-               {
-                 string_clear (declp);
-                 string_append (declp, "operator");
-                 string_append (declp, optable[i].out);
-                 break;
-               }
-           }
-       }
-      else
-       {
-         if (declp->b[2] == 'a' && declp->b[5] == '\0')
-           {
-             /* Assignment.  */
-             for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
-               {
-                 if (strlen (optable[i].in) == 3
-                     && memcmp (optable[i].in, declp->b + 2, 3) == 0)
-                   {
-                     string_clear (declp);
-                     string_append (declp, "operator");
-                     string_append (declp, optable[i].out);
-                     break;
-                   }                 
-               }
-           }
-       }
-    }
-}
-
-/* a mini string-handling package */
-
-static void
-string_need (s, n)
-     string *s;
-     int n;
-{
-  int tem;
-
-  if (s->b == NULL)
-    {
-      if (n < 32)
-       {
-         n = 32;
-       }
-      s->p = s->b = xmalloc (n);
-      s->e = s->b + n;
-    }
-  else if (s->e - s->p < n)
-    {
-      tem = s->p - s->b;
-      n += tem;
-      n *= 2;
-      s->b = xrealloc (s->b, n);
-      s->p = s->b + tem;
-      s->e = s->b + n;
-    }
-}
-
-static void
-string_delete (s)
-     string *s;
-{
-  if (s->b != NULL)
-    {
-      free (s->b);
-      s->b = s->e = s->p = NULL;
-    }
-}
-
-static void
-string_init (s)
-     string *s;
-{
-  s->b = s->p = s->e = NULL;
-}
-
-static void 
-string_clear (s)
-     string *s;
-{
-  s->p = s->b;
-}
-
-#if 0
-
-static int
-string_empty (s)
-     string *s;
-{
-  return (s->b == s->p);
-}
-
-#endif
-
-static void
-string_append (p, s)
-     string *p;
-     const char *s;
-{
-  int n;
-  if (s == NULL || *s == '\0')
-    return;
-  n = strlen (s);
-  string_need (p, n);
-  memcpy (p->p, s, n);
-  p->p += n;
-}
-
-static void
-string_appends (p, s)
-     string *p, *s;
-{
-  int n;
-
-  if (s->b != s->p)
-    {
-      n = s->p - s->b;
-      string_need (p, n);
-      memcpy (p->p, s->b, n);
-      p->p += n;
-    }
-}
-
-static void
-string_appendn (p, s, n)
-     string *p;
-     const char *s;
-     int n;
-{
-  if (n != 0)
-    {
-      string_need (p, n);
-      memcpy (p->p, s, n);
-      p->p += n;
-    }
-}
-
-static void
-string_prepend (p, s)
-     string *p;
-     const char *s;
-{
-  if (s != NULL && *s != '\0')
-    {
-      string_prependn (p, s, strlen (s));
-    }
-}
-
-static void
-string_prepends (p, s)
-     string *p, *s;
-{
-  if (s->b != s->p)
-    {
-      string_prependn (p, s->b, s->p - s->b);
-    }
-}
-
-static void
-string_prependn (p, s, n)
-     string *p;
-     const char *s;
-     int n;
-{
-  char *q;
-
-  if (n != 0)
-    {
-      string_need (p, n);
-      for (q = p->p - 1; q >= p->b; q--)
-       {
-         q[n] = q[0];
-       }
-      memcpy (p->b, s, n);
-      p->p += n;
-    }
-}
-
-/* To generate a standalone demangler program for testing purposes,
-   just compile and link this file with -DMAIN and libiberty.a.  When
-   run, it demangles each command line arg, or each stdin string, and
-   prints the result on stdout.  */
-
-#ifdef MAIN
-
-#include "getopt.h"
-
-static char *program_name;
-static char *program_version = VERSION;
-static int flags = DMGL_PARAMS | DMGL_ANSI;
-
-static void demangle_it PARAMS ((char *));
-static void usage PARAMS ((FILE *, int));
-static void fatal PARAMS ((char *));
-
-static void
-demangle_it (mangled_name)
-     char *mangled_name;
-{
-  char *result;
-
-  result = cplus_demangle (mangled_name, flags);
-  if (result == NULL)
-    {
-      printf ("%s\n", mangled_name);
-    }
-  else
-    {
-      printf ("%s\n", result);
-      free (result);
-    }
-}
-
-static void
-usage (stream, status)
-     FILE *stream;
-     int status;
-{    
-  fprintf (stream, "\
-Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
-      [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
-      [--help] [--version] [arg...]\n",
-          program_name);
-  exit (status);
-}
-
-#define MBUF_SIZE 32767
-char mbuffer[MBUF_SIZE];
-
-/* Defined in the automatically-generated underscore.c.  */
-extern int prepends_underscore;
-
-int strip_underscore = 0;
-
-static struct option long_options[] = {
-  {"strip-underscores", no_argument, 0, '_'},
-  {"format", required_argument, 0, 's'},
-  {"help", no_argument, 0, 'h'},
-  {"no-strip-underscores", no_argument, 0, 'n'},
-  {"version", no_argument, 0, 'v'},
-  {0, no_argument, 0, 0}
-};
-
-/* More 'friendly' abort that prints the line and file.
-   config.h can #define abort fancy_abort if you like that sort of thing.  */
-
-void
-fancy_abort ()
-{
-  fatal ("Internal gcc abort.");
-}
-
-int
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  char *result;
-  int c;
-
-  program_name = argv[0];
-
-  strip_underscore = prepends_underscore;
-
-  while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
-    {
-      switch (c)
-       {
-       case '?':
-         usage (stderr, 1);
-         break;
-       case 'h':
-         usage (stdout, 0);
-       case 'n':
-         strip_underscore = 0;
-         break;
-       case 'v':
-         printf ("GNU %s version %s\n", program_name, program_version);
-         exit (0);
-       case '_':
-         strip_underscore = 1;
-         break;
-       case 's':
-         if (strcmp (optarg, "gnu") == 0)
-           {
-             current_demangling_style = gnu_demangling;
-           }
-         else if (strcmp (optarg, "lucid") == 0)
-           {
-             current_demangling_style = lucid_demangling;
-           }
-         else if (strcmp (optarg, "arm") == 0)
-           {
-             current_demangling_style = arm_demangling;
-           }
-         else
-           {
-             fprintf (stderr, "%s: unknown demangling style `%s'\n",
-                      program_name, optarg);
-             exit (1);
-           }
-         break;
-       }
-    }
-
-  if (optind < argc)
-    {
-      for ( ; optind < argc; optind++)
-       {
-         demangle_it (argv[optind]);
-       }
-    }
-  else
-    {
-      for (;;)
-       {
-         int i = 0;
-         c = getchar ();
-         /* Try to read a label.  */
-         while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
-           {
-             if (i >= MBUF_SIZE-1)
-               break;
-             mbuffer[i++] = c;
-             c = getchar ();
-           }
-         if (i > 0)
-           {
-             int skip_first = 0;
-
-             if (mbuffer[0] == '.')
-               ++skip_first;
-             if (strip_underscore && mbuffer[skip_first] == '_')
-               ++skip_first;
-
-             if (skip_first > i)
-               skip_first = i;
-
-             mbuffer[i] = 0;
-             
-             result = cplus_demangle (mbuffer + skip_first, flags);
-             if (result)
-               {
-                 if (mbuffer[0] == '.')
-                   putc ('.', stdout);
-                 fputs (result, stdout);
-                 free (result);
-               }
-             else
-               fputs (mbuffer, stdout);
-
-             fflush (stdout);
-           }
-         if (c == EOF)
-           break;
-         putchar (c);
-       }
-    }
-
-  exit (0);
-}
-
-static void
-fatal (str)
-     char *str;
-{
-  fprintf (stderr, "%s: %s\n", program_name, str);
-  exit (1);
-}
-
-char * malloc ();
-char * realloc ();
-
-char *
-xmalloc (size)
-     unsigned size;
-{
-  register char *value = (char *) malloc (size);
-  if (value == 0)
-    fatal ("virtual memory exhausted");
-  return value;
-}
-
-char *
-xrealloc (ptr, size)
-     char *ptr;
-     unsigned size;
-{
-  register char *value = (char *) realloc (ptr, size);
-  if (value == 0)
-    fatal ("virtual memory exhausted");
-  return value;
-}
-#endif /* main */
index c84d52c9724a02802e20e8059f878034ae61ca91..8a289a8170945082a7e53f2ab118a3fcf54b1fa4 100644 (file)
@@ -47,6 +47,7 @@ Boston, MA 02111-1307, USA.  */
 #include <setjmp.h>
 #include "flags.h"
 #include "tree.h"
+#include "rtl.h"
 #include "toplev.h"
 
 /* Handle floating overflow for `const_binop'.  */
index c5d1505e9e2eff8789deed1c521be1f85fc00219..ba7c45c2be353a54c8962763329dfcb11bc00346 100644 (file)
@@ -6053,7 +6053,7 @@ express_from_1 (a, b, mult)
 
   if (GET_CODE (a) == PLUS)
     {
-      rtx ra, oa, tmp;
+      rtx ra, oa;
 
       ra = XEXP (a, 0), oa = XEXP (a, 1);
       if (rtx_equal_p (oa, b))
@@ -6251,10 +6251,10 @@ combine_givs (bl)
       giv_array[i++] = g1;
 
   stats = (struct combine_givs_stats *) alloca (giv_count * sizeof (*stats));
-  bzero (stats, giv_count * sizeof (*stats));
+  bzero ((char *) stats, giv_count * sizeof (*stats));
 
   can_combine = (rtx *) alloca (giv_count * giv_count * sizeof(rtx));
-  bzero (can_combine, giv_count * giv_count * sizeof(rtx));
+  bzero ((char *) can_combine, giv_count * giv_count * sizeof(rtx));
 
   for (i = 0; i < giv_count; i++)
     {
index dba8d2f5b2a64f0e88a4c2c811ea89dfbd5d86bf..976f8a1cd1cf0f797071a2a1fbf6b3a5472fd898 100644 (file)
@@ -4021,8 +4021,6 @@ display_help ()
   
   if (NUM_ELEM (documented_lang_options) > 1)
     {
-      int       looking_for_start = 0;
-      
       printf ("\nLanguage specific options:\n");
 
       for (i = 0; i < NUM_ELEM (documented_lang_options); i++)