]> gcc.gnu.org Git - gcc.git/commitdiff
cplus-dem.c: Add code to enable demangling of names produced with the -fsquangle...
authorAndrew MacLeod <amacleod@cygnus.com>
Wed, 22 Apr 1998 08:04:13 +0000 (08:04 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Wed, 22 Apr 1998 08:04:13 +0000 (08:04 +0000)
* cplus-dem.c:  Add code to enable demangling of names produced
                with the -fsquangle option.

From-SVN: r19371

gcc/ChangeLog
gcc/cplus-dem.c
libiberty/ChangeLog
libiberty/cplus-dem.c

index 779e3c6897eaa66bc070f09795b2cae2dc884ecf..dd3fa3c0a3fc78d4d7042b605f91ec790e208982 100644 (file)
@@ -1,3 +1,22 @@
+Wed Apr 22 10:53:49 EDT 1998 Andrew MacLeod  <amacleod@cygnus.com>
+
+       * cplus-dem.c (struct work stuff): Add field for B and K mangle codes.
+       (cplus_demangle_opname): Call mop_up_squangle.
+       (cplus_demangle): Initialize squangle info, then call 
+       internal_cplus_demangle. (Most code moved there as well)
+       (internal_cplus_demangle): New function, performs most of what use 
+       to be done in cplus_demangle, but is only called with this file.
+       (squangle_mop_up): New function to clean up B and K code data.
+       (mop_up): set pointers to NULL after freeing.
+       (demangle_signature, demangle_template, demangle_class): Add 
+       switch elements to handle K and B codes.
+       (demangle_prefix, gnu_special, demangle_qualified): Add
+       code to handle K and B codes.
+       (do_type, demangle_fund_type): Handle B and K codes.
+       (remember_Ktype): New function to store K info.
+       (register_Btype, remember_Btype): New functions for B codes.
+       (forget_B_and_K_types): New function to destroy B and K info.
+
 1998-04-21  Jim Wilson  <wilson@cygnus.com>
 
        * stmt.c (check_seenlabel): When search for line number note for
index acdbfa897e2e090aaf3250456aecbdb2ae4a6f2e..abc85bbe5d1cd0d766cf312a3c3aad2333e8b9ff 100644 (file)
@@ -101,6 +101,12 @@ 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;
@@ -214,6 +220,7 @@ typedef struct string               /* Beware: these aren't required to be */
     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))
 
 #define ARM_VTABLE_STRING "__vtbl__"   /* Lucid/ARM virtual table prefix */
 #define ARM_VTABLE_STRLEN 8            /* strlen (ARM_VTABLE_STRING) */
@@ -223,11 +230,17 @@ typedef struct string             /* Beware: these aren't required to be */
 static char *
 mop_up PARAMS ((struct work_stuff *, string *, int));
 
+static char *
+squangle_mop_up PARAMS ((struct work_stuff *));
+
 #if 0
 static int
-demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
+demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
 #endif
 
+static char *
+internal_cplus_demangle PARAMS ((struct work_stuff *, const char *, int));
+
 static int
 demangle_template_template_parm PARAMS ((struct work_stuff *work, 
                                         const char **, string *));
@@ -325,9 +338,21 @@ demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
 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 *));
 
@@ -511,6 +536,7 @@ cplus_demangle_opname (opname, result, options)
          ret = 1;
        }
     }
+  squangle_mop_up (work);
   return ret;
 
 }
@@ -572,18 +598,45 @@ 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, options);
+  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, options)
+     struct work_stuff *work;
+     const char *mangled;
+     int options;
+{
+
   string decl;
   int success = 0;
-  struct work_stuff work[1];
   char *demangled = NULL;
+  int s1,s2,s3,s4;
+  s1 = work->constructor;
+  s2 = work->destructor;
+  s3 = work->static_type;
+  s4 = work->const_type;
+  work->constructor = work->destructor = 0;
+  work->static_type = work->const_type = 0;
 
   if ((mangled != NULL) && (*mangled != '\0'))
     {
-      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;
-      
       string_init (&decl);
 
       /* First check to see if gnu style demangling is active and if the
@@ -607,19 +660,43 @@ cplus_demangle (mangled, options)
        }
       if (work->constructor == 2)
         {
-          string_prepend(&decl, "global constructors keyed to ");
+          string_prepend (&decl, "global constructors keyed to ");
           work->constructor = 0;
         }
       else if (work->destructor == 2)
         {
-          string_prepend(&decl, "global destructors keyed to ");
+          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;
   return (demangled);
 }
 
+
+/* Clear out and squangling related storage */
+static char *
+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;
@@ -634,6 +711,7 @@ mop_up (work, declp, success)
   if (work -> typevec != NULL)
     {
       free ((char *) work -> typevec);
+      work -> typevec = NULL;
     }
   if (work->tmpl_argvec)
     {
@@ -644,6 +722,7 @@ mop_up (work, declp, success)
          free ((char*) work->tmpl_argvec[i]);
       
       free ((char*) work->tmpl_argvec);
+      work->tmpl_argvec = NULL;
     }
 
   /* If demangling was successful, ensure that the demangled string is null
@@ -722,6 +801,16 @@ demangle_signature (work, mangled, declp)
            }
          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 */
@@ -1061,7 +1150,7 @@ demangle_integral_value (work, mangled, s)
          (*mangled)++;
        }
     }
-  else if (**mangled == 'Q')
+  else if (**mangled == 'Q' || **mangled == 'K')
     success = demangle_qualified (work, mangled, s, 0, 1);
   else
     {
@@ -1119,6 +1208,10 @@ demangle_template_value_parm (work, mangled, s)
          continue;
        case 'E':       /* expression */
        case 'Q':       /* qualified name */
+       case 'K':       /* qualified name */
+         done = is_integral = 1;
+         break;
+       case 'B':       /* squangled name */
          done = is_integral = 1;
          break;
        case 'T':       /* remembered type */
@@ -1247,7 +1340,7 @@ demangle_template_value_parm (work, mangled, s)
          char *p = xmalloc (symbol_len + 1), *q;
          strncpy (p, *mangled, symbol_len);
          p [symbol_len] = '\0';
-         q = cplus_demangle (p, work->options);
+         q = internal_cplus_demangle (work, p, work->options);
          string_appendn (s, "&", 1);
          if (q)
            {
@@ -1604,9 +1697,11 @@ demangle_class (work, mangled, declp)
      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))
@@ -1622,6 +1717,8 @@ demangle_class (work, mangled, declp)
              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, (work -> options & DMGL_JAVA) ? "." : "::");
       string_prepends (declp, &class_name);
       success = 1;
@@ -1745,7 +1842,7 @@ demangle_prefix (work, mangled, declp)
     }
   else if ((scan == *mangled)
           && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
-              || (scan[2] == 'H')))
+              || (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>
@@ -1892,6 +1989,7 @@ gnu_special (work, mangled, declp)
          switch (**mangled)
            {
            case 'Q':
+           case 'K':
              success = demangle_qualified (work, mangled, declp, 0, 1);
              break;
            case 't':
@@ -1946,6 +2044,7 @@ gnu_special (work, mangled, declp)
       switch (**mangled)
        {
        case 'Q':
+       case 'K':
          success = demangle_qualified (work, mangled, declp, 0, 1);
          break;
        case 't':
@@ -1974,7 +2073,7 @@ gnu_special (work, mangled, declp)
   else if (strncmp (*mangled, "__thunk_", 8) == 0)
     {
       int delta = ((*mangled) += 8, consume_count (mangled));
-      char *method = cplus_demangle (++*mangled, work->options);
+      char *method = internal_cplus_demangle (work, ++*mangled, work->options);
       if (method)
        {
          char buf[50];
@@ -1998,6 +2097,7 @@ gnu_special (work, mangled, declp)
       switch (**mangled)
        {
        case 'Q':
+       case 'K':
          success = demangle_qualified (work, mangled, declp, 0, 1);
          break;
        case 't':
@@ -2132,7 +2232,7 @@ demangle_qualified (work, mangled, result, isfuncname, append)
      int isfuncname;
      int append;
 {
-  int qualifiers;
+  int qualifiers = 0;
   int namelength;
   int success = 1;
   const char *p;
@@ -2140,7 +2240,20 @@ demangle_qualified (work, mangled, result, isfuncname, append)
   string temp;
 
   string_init (&temp);
-  switch ((*mangled)[1])
+
+  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
@@ -2198,6 +2311,7 @@ demangle_qualified (work, mangled, result, isfuncname, append)
 
   while (qualifiers-- > 0)
     {
+      int remember_K = 1;
       if (*mangled[0] == '_') 
        *mangled = *mangled + 1;
       if (*mangled[0] == 't')
@@ -2208,6 +2322,19 @@ demangle_qualified (work, mangled, result, isfuncname, append)
       else if (*mangled[0] == 'X')
        {
          success = do_type (work, mangled, &temp);
+         if (!success) break;
+       }
+      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
@@ -2222,6 +2349,12 @@ demangle_qualified (work, mangled, result, isfuncname, append)
          string_appendn (&temp, *mangled, namelength);
          *mangled += namelength;
        }
+
+      if (remember_K)
+        {
+        remember_Ktype (work, temp.b, LEN_STRING (&temp));
+        }
+
       if (qualifiers > 0)
         {
           string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
@@ -2331,7 +2464,9 @@ do_type (work, mangled, result)
   const char *remembered_type;
   int constp;
   int volatilep;
+  string btype;
 
+  string_init (&btype);
   string_init (&decl);
   string_init (result);
 
@@ -2531,7 +2666,24 @@ do_type (work, mangled, result)
     {
       /* A qualified name, such as "Outer::Inner".  */
     case 'Q':
-      success = demangle_qualified (work, mangled, result, 0, 1);
+    case 'K':
+      {
+        int btype = register_Btype (work);
+        success = demangle_qualified (work, mangled, result, 0, 1);
+        remember_Btype (work, result->b, LEN_STRING (result), btype);
+
+        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':
@@ -2606,6 +2758,8 @@ demangle_fund_type (work, mangled, result)
 {
   int done = 0;
   int success = 1;
+  string btype;
+  string_init (&btype);
 
   /* First pick off any type qualifiers.  There can be more than one.  */
 
@@ -2731,15 +2885,28 @@ demangle_fund_type (work, mangled, result)
     case '7':
     case '8':
     case '9':
-      APPEND_BLANK (result);
-      if (!demangle_class_name (work, mangled, result)) {
-       --result->p;
-       success = 0;
+      {
+        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;
       }
-      break;
     case 't':
-      success = demangle_template(work,mangled, result, 0, 1);
-      break;
+      {
+        int bindex= register_Btype (work);
+        success = demangle_template (work, mangled, &btype, 0, 1);
+        remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+        string_appends (result, &btype);
+        break;
+      }
     default:
       success = 0;
       break;
@@ -2799,6 +2966,112 @@ remember_type (work, start, len)
   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
index 1acd2f3f4a5a79f3cb205ae492cca868f5e8445b..acd96f248eba4d5dc43637be500953d85a3893ef 100644 (file)
@@ -1,3 +1,22 @@
+Wed Apr 22 10:53:49 EDT 1998 Andrew MacLeod  <amacleod@cygnus.com>
+
+       * cplus-dem.c (struct work stuff): Add field for B and K mangle codes.
+       (cplus_demangle_opname): Call mop_up_squangle.
+       (cplus_demangle): Initialize squangle info, then call 
+       internal_cplus_demangle. (Most code moved there as well)
+       (internal_cplus_demangle): New function, performs most of what use 
+       to be done in cplus_demangle, but is only called with this file.
+       (squangle_mop_up): New function to clean up B and K code data.
+       (mop_up): set pointers to NULL after freeing.
+       (demangle_signature, demangle_template, demangle_class): Add 
+       switch elements to handle K and B codes.
+       (demangle_prefix, gnu_special, demangle_qualified): Add
+       code to handle K and B codes.
+       (do_type, demangle_fund_type): Handle B and K codes.
+       (remember_Ktype): New function to store K info.
+       (register_Btype, remember_Btype): New functions for B codes.
+       (forget_B_and_K_types): New function to destroy B and K info.
+
 Fri Apr 10 01:45:09 1998  Jeffrey A Law  (law@cygnus.com)
 
        * cplus-dem.c: Sync with gcc.
index acdbfa897e2e090aaf3250456aecbdb2ae4a6f2e..abc85bbe5d1cd0d766cf312a3c3aad2333e8b9ff 100644 (file)
@@ -101,6 +101,12 @@ 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;
@@ -214,6 +220,7 @@ typedef struct string               /* Beware: these aren't required to be */
     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))
 
 #define ARM_VTABLE_STRING "__vtbl__"   /* Lucid/ARM virtual table prefix */
 #define ARM_VTABLE_STRLEN 8            /* strlen (ARM_VTABLE_STRING) */
@@ -223,11 +230,17 @@ typedef struct string             /* Beware: these aren't required to be */
 static char *
 mop_up PARAMS ((struct work_stuff *, string *, int));
 
+static char *
+squangle_mop_up PARAMS ((struct work_stuff *));
+
 #if 0
 static int
-demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
+demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
 #endif
 
+static char *
+internal_cplus_demangle PARAMS ((struct work_stuff *, const char *, int));
+
 static int
 demangle_template_template_parm PARAMS ((struct work_stuff *work, 
                                         const char **, string *));
@@ -325,9 +338,21 @@ demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
 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 *));
 
@@ -511,6 +536,7 @@ cplus_demangle_opname (opname, result, options)
          ret = 1;
        }
     }
+  squangle_mop_up (work);
   return ret;
 
 }
@@ -572,18 +598,45 @@ 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, options);
+  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, options)
+     struct work_stuff *work;
+     const char *mangled;
+     int options;
+{
+
   string decl;
   int success = 0;
-  struct work_stuff work[1];
   char *demangled = NULL;
+  int s1,s2,s3,s4;
+  s1 = work->constructor;
+  s2 = work->destructor;
+  s3 = work->static_type;
+  s4 = work->const_type;
+  work->constructor = work->destructor = 0;
+  work->static_type = work->const_type = 0;
 
   if ((mangled != NULL) && (*mangled != '\0'))
     {
-      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;
-      
       string_init (&decl);
 
       /* First check to see if gnu style demangling is active and if the
@@ -607,19 +660,43 @@ cplus_demangle (mangled, options)
        }
       if (work->constructor == 2)
         {
-          string_prepend(&decl, "global constructors keyed to ");
+          string_prepend (&decl, "global constructors keyed to ");
           work->constructor = 0;
         }
       else if (work->destructor == 2)
         {
-          string_prepend(&decl, "global destructors keyed to ");
+          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;
   return (demangled);
 }
 
+
+/* Clear out and squangling related storage */
+static char *
+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;
@@ -634,6 +711,7 @@ mop_up (work, declp, success)
   if (work -> typevec != NULL)
     {
       free ((char *) work -> typevec);
+      work -> typevec = NULL;
     }
   if (work->tmpl_argvec)
     {
@@ -644,6 +722,7 @@ mop_up (work, declp, success)
          free ((char*) work->tmpl_argvec[i]);
       
       free ((char*) work->tmpl_argvec);
+      work->tmpl_argvec = NULL;
     }
 
   /* If demangling was successful, ensure that the demangled string is null
@@ -722,6 +801,16 @@ demangle_signature (work, mangled, declp)
            }
          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 */
@@ -1061,7 +1150,7 @@ demangle_integral_value (work, mangled, s)
          (*mangled)++;
        }
     }
-  else if (**mangled == 'Q')
+  else if (**mangled == 'Q' || **mangled == 'K')
     success = demangle_qualified (work, mangled, s, 0, 1);
   else
     {
@@ -1119,6 +1208,10 @@ demangle_template_value_parm (work, mangled, s)
          continue;
        case 'E':       /* expression */
        case 'Q':       /* qualified name */
+       case 'K':       /* qualified name */
+         done = is_integral = 1;
+         break;
+       case 'B':       /* squangled name */
          done = is_integral = 1;
          break;
        case 'T':       /* remembered type */
@@ -1247,7 +1340,7 @@ demangle_template_value_parm (work, mangled, s)
          char *p = xmalloc (symbol_len + 1), *q;
          strncpy (p, *mangled, symbol_len);
          p [symbol_len] = '\0';
-         q = cplus_demangle (p, work->options);
+         q = internal_cplus_demangle (work, p, work->options);
          string_appendn (s, "&", 1);
          if (q)
            {
@@ -1604,9 +1697,11 @@ demangle_class (work, mangled, declp)
      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))
@@ -1622,6 +1717,8 @@ demangle_class (work, mangled, declp)
              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, (work -> options & DMGL_JAVA) ? "." : "::");
       string_prepends (declp, &class_name);
       success = 1;
@@ -1745,7 +1842,7 @@ demangle_prefix (work, mangled, declp)
     }
   else if ((scan == *mangled)
           && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
-              || (scan[2] == 'H')))
+              || (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>
@@ -1892,6 +1989,7 @@ gnu_special (work, mangled, declp)
          switch (**mangled)
            {
            case 'Q':
+           case 'K':
              success = demangle_qualified (work, mangled, declp, 0, 1);
              break;
            case 't':
@@ -1946,6 +2044,7 @@ gnu_special (work, mangled, declp)
       switch (**mangled)
        {
        case 'Q':
+       case 'K':
          success = demangle_qualified (work, mangled, declp, 0, 1);
          break;
        case 't':
@@ -1974,7 +2073,7 @@ gnu_special (work, mangled, declp)
   else if (strncmp (*mangled, "__thunk_", 8) == 0)
     {
       int delta = ((*mangled) += 8, consume_count (mangled));
-      char *method = cplus_demangle (++*mangled, work->options);
+      char *method = internal_cplus_demangle (work, ++*mangled, work->options);
       if (method)
        {
          char buf[50];
@@ -1998,6 +2097,7 @@ gnu_special (work, mangled, declp)
       switch (**mangled)
        {
        case 'Q':
+       case 'K':
          success = demangle_qualified (work, mangled, declp, 0, 1);
          break;
        case 't':
@@ -2132,7 +2232,7 @@ demangle_qualified (work, mangled, result, isfuncname, append)
      int isfuncname;
      int append;
 {
-  int qualifiers;
+  int qualifiers = 0;
   int namelength;
   int success = 1;
   const char *p;
@@ -2140,7 +2240,20 @@ demangle_qualified (work, mangled, result, isfuncname, append)
   string temp;
 
   string_init (&temp);
-  switch ((*mangled)[1])
+
+  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
@@ -2198,6 +2311,7 @@ demangle_qualified (work, mangled, result, isfuncname, append)
 
   while (qualifiers-- > 0)
     {
+      int remember_K = 1;
       if (*mangled[0] == '_') 
        *mangled = *mangled + 1;
       if (*mangled[0] == 't')
@@ -2208,6 +2322,19 @@ demangle_qualified (work, mangled, result, isfuncname, append)
       else if (*mangled[0] == 'X')
        {
          success = do_type (work, mangled, &temp);
+         if (!success) break;
+       }
+      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
@@ -2222,6 +2349,12 @@ demangle_qualified (work, mangled, result, isfuncname, append)
          string_appendn (&temp, *mangled, namelength);
          *mangled += namelength;
        }
+
+      if (remember_K)
+        {
+        remember_Ktype (work, temp.b, LEN_STRING (&temp));
+        }
+
       if (qualifiers > 0)
         {
           string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
@@ -2331,7 +2464,9 @@ do_type (work, mangled, result)
   const char *remembered_type;
   int constp;
   int volatilep;
+  string btype;
 
+  string_init (&btype);
   string_init (&decl);
   string_init (result);
 
@@ -2531,7 +2666,24 @@ do_type (work, mangled, result)
     {
       /* A qualified name, such as "Outer::Inner".  */
     case 'Q':
-      success = demangle_qualified (work, mangled, result, 0, 1);
+    case 'K':
+      {
+        int btype = register_Btype (work);
+        success = demangle_qualified (work, mangled, result, 0, 1);
+        remember_Btype (work, result->b, LEN_STRING (result), btype);
+
+        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':
@@ -2606,6 +2758,8 @@ demangle_fund_type (work, mangled, result)
 {
   int done = 0;
   int success = 1;
+  string btype;
+  string_init (&btype);
 
   /* First pick off any type qualifiers.  There can be more than one.  */
 
@@ -2731,15 +2885,28 @@ demangle_fund_type (work, mangled, result)
     case '7':
     case '8':
     case '9':
-      APPEND_BLANK (result);
-      if (!demangle_class_name (work, mangled, result)) {
-       --result->p;
-       success = 0;
+      {
+        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;
       }
-      break;
     case 't':
-      success = demangle_template(work,mangled, result, 0, 1);
-      break;
+      {
+        int bindex= register_Btype (work);
+        success = demangle_template (work, mangled, &btype, 0, 1);
+        remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+        string_appends (result, &btype);
+        break;
+      }
     default:
       success = 0;
       break;
@@ -2799,6 +2966,112 @@ remember_type (work, start, len)
   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
This page took 0.132296 seconds and 5 git commands to generate.