gas: avoid spurious failures in non-ELF targets in the SPARC testsuite.
[deliverable/binutils-gdb.git] / libiberty / cplus-dem.c
index f20a5ef9d84fada95f06458e0e6fdeb05ce85667..c68b9813de25c6ee39e5288bf74649a1d2de3965 100644 (file)
@@ -1,6 +1,6 @@
 /* Demangler for GNU C++
    Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
    Written by James Clark (jjc@jclark.uucp)
    Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
    Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
@@ -305,6 +305,12 @@ const struct demangler_engine libiberty_demanglers[] =
     "GNAT style demangling"
   }
   ,
+  {
+    DLANG_DEMANGLING_STYLE_STRING,
+    dlang_demangling,
+    "DLANG style demangling"
+  }
+  ,
   {
     NULL, unknown_demangling, NULL
   }
@@ -870,6 +876,13 @@ cplus_demangle (const char *mangled, int options)
   if (GNAT_DEMANGLING)
     return ada_demangle (mangled, options);
 
+  if (DLANG_DEMANGLING)
+    {
+      ret = dlang_demangle (mangled, options);
+      if (ret)
+       return ret;
+    }
+
   ret = internal_cplus_demangle (work, mangled);
   squangle_mop_up (work);
   return (ret);
@@ -895,18 +908,20 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
 
   /* Most of the demangling will trivially remove chars.  Operator names
      may add one char but because they are always preceeded by '__' which is
-     replaced by '.', they eventually never expand the size.  '___elabs' and
-     '___elabb' add only 2 chars, but they occur only once.  */
-  len0 = strlen (mangled) + 2 + 1;
+     replaced by '.', they eventually never expand the size.
+     A few special names such as '___elabs' add a few chars (at most 7), but
+     they occur only once.  */
+  len0 = strlen (mangled) + 7 + 1;
   demangled = XNEWVEC (char, len0);
   
   d = demangled;
   p = mangled;
   while (1)
     {
-      /* Convert name, which is always lower-case.  */
+      /* An entity names is expected.  */
       if (ISLOWER (*p))
         {
+          /* An identifier, which is always lower case.  */
           do
             *d++ = *p++;
           while (ISLOWER(*p) || ISDIGIT (*p)
@@ -914,6 +929,7 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
         }
       else if (p[0] == 'O')
         {
+          /* An operator name.  */
           static const char * const operators[][2] =
             {{"Oabs", "abs"},  {"Oand", "and"},    {"Omod", "mod"},
              {"Onot", "not"},  {"Oor", "or"},      {"Orem", "rem"},
@@ -924,22 +940,22 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
              {"Oexpon", "**"}, {NULL, NULL}};
           int k;
 
-          for (k = 0; operators[k][0]; k++)
+          for (k = 0; operators[k][0] != NULL; k++)
             {
-              int l = strlen (operators[k][0]);
-              if (!strncmp (p, operators[k][0], l))
+              size_t slen = strlen (operators[k][0]);
+              if (strncmp (p, operators[k][0], slen) == 0)
                 {
-                  p += l;
-                  l = strlen (operators[k][1]);
+                  p += slen;
+                  slen = strlen (operators[k][1]);
                   *d++ = '"';
-                  memcpy (d, operators[k][1], l);
-                  d += l;
+                  memcpy (d, operators[k][1], slen);
+                  d += slen;
                   *d++ = '"';
                   break;
                 }
             }
           /* Operator not found.  */
-          if (!operators[k][0])
+          if (operators[k][0] == NULL)
             goto unknown;
         }
       else
@@ -948,6 +964,92 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
           goto unknown;
         }
 
+      /* The name can be directly followed by some uppercase letters.  */
+      if (p[0] == 'T' && p[1] == 'K')
+        {
+          /* Task stuff.  */
+          if (p[2] == 'B' && p[3] == 0)
+            {
+              /* Subprogram for task body.  */
+              break;
+            }
+          else if (p[2] == '_' && p[3] == '_')
+            {
+              /* Inner declarations in a task.  */
+              p += 4;
+              *d++ = '.';
+              continue;
+            }
+          else
+            goto unknown;
+        }
+      if (p[0] == 'E' && p[1] == 0)
+        {
+          /* Exception name.  */
+          goto unknown;
+        }
+      if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
+        {
+          /* Protected type subprogram.  */
+          break;
+        }
+      if ((*p == 'N' || *p == 'S') && p[1] == 0)
+        {
+          /* Enumerated type name table.  */
+          goto unknown;
+        }
+      if (p[0] == 'X')
+        {
+          /* Body nested.  */
+          p++;
+          while (p[0] == 'n' || p[0] == 'b')
+            p++;
+        }
+      if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
+        {
+          /* Stream operations.  */
+          const char *name;
+          switch (p[1])
+            {
+            case 'R':
+              name = "'Read";
+              break;
+            case 'W':
+              name = "'Write";
+              break;
+            case 'I':
+              name = "'Input";
+              break;
+            case 'O':
+              name = "'Output";
+              break;
+            default:
+              goto unknown;
+            }
+          p += 2;
+          strcpy (d, name);
+          d += strlen (name);
+        }
+      else if (p[0] == 'D')
+        {
+          /* Controlled type operation.  */
+          const char *name;
+          switch (p[1])
+            {
+            case 'F':
+              name = ".Finalize";
+              break;
+            case 'A':
+              name = ".Adjust";
+              break;
+            default:
+              goto unknown;
+            }
+          strcpy (d, name);
+          d += strlen (name);
+          break;
+        }
+
       if (p[0] == '_')
         {
           /* Separator.  */
@@ -955,24 +1057,49 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
             {
               /* Standard separator.  Handled first.  */
               p += 2;
+
               if (ISDIGIT (*p))
                 {
-                  /* Overloading.  */
+                  /* Overloading number.  */
                   do
                     p++;
                   while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
+                  if (*p == 'X')
+                    {
+                      p++;
+                      while (p[0] == 'n' || p[0] == 'b')
+                        p++;
+                    }
                 }
-              else if (*p == '_' && !strcmp (p + 1, "elabb"))
+              else if (p[0] == '_' && p[1] != '_')
                 {
-                  memcpy (d, "'Elab_Body", 10);
-                  d += 10;
-                  break;
-                }
-              else if (*p == '_' && !strcmp (p + 1, "elabs"))
-                {
-                  memcpy (d, "'Elab_Spec", 10);
-                  d += 10;
-                  break;
+                  /* Special names.  */
+                  static const char * const special[][2] = {
+                    { "_elabb", "'Elab_Body" },
+                    { "_elabs", "'Elab_Spec" },
+                    { "_size", "'Size" },
+                    { "_alignment", "'Alignment" },
+                    { "_assign", ".\":=\"" },
+                    { NULL, NULL }
+                  };
+                  int k;
+
+                  for (k = 0; special[k][0] != NULL; k++)
+                    {
+                      size_t slen = strlen (special[k][0]);
+                      if (strncmp (p, special[k][0], slen) == 0)
+                        {
+                          p += slen;
+                          slen = strlen (special[k][1]);
+                          memcpy (d, special[k][1], slen);
+                          d += slen;
+                          break;
+                        }
+                    }
+                  if (special[k][0] != NULL)
+                    break;
+                  else
+                    goto unknown;
                 }
               else
                 {
@@ -995,46 +1122,6 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
             goto unknown;
         }
 
-      if (p[0] == 'T' && p[1] == 'K')
-        {
-          if (p[2] == 'B' && p[3] == 0)
-            {
-              /* Subprogram for task body.  */
-              break;
-            }
-          else if (p[2] == '_' && p[3] == '_')
-            {
-              /* Inner declarations in a task.  */
-              p += 4;
-              *d++ = '.';
-              continue;
-            }
-          else
-            goto unknown;
-        }
-      if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
-        {
-          /* Protected type subprogram.  */
-          break;
-        }
-      if (p[0] == 'E' && p[1] == 0)
-        {
-          /* Exception name.  */
-          goto unknown;
-        }
-      if (*p == 'N' || *p == 'S')
-        {
-          /* Enumerated type name table.  */
-          goto unknown;
-        }
-      if (p[0] == 'X')
-        {
-          /* Body nested.  */
-          if (p[1] == 'n' || p[1] == 'b')
-            p += 2;
-          else if (p[1] == 0)
-            p++;
-        }
       if (p[0] == '.' && ISDIGIT (p[1]))
         {
           /* Nested subprogram.  */
@@ -1101,6 +1188,11 @@ internal_cplus_demangle (struct work_stuff *work, const char *mangled)
       if ((AUTO_DEMANGLING || GNU_DEMANGLING))
        {
          success = gnu_special (work, &mangled, &decl);
+         if (!success)
+           {
+             delete_work_stuff (work);
+             string_delete (&decl);
+           }
        }
       if (!success)
        {
@@ -1144,10 +1236,12 @@ squangle_mop_up (struct work_stuff *work)
   if (work -> btypevec != NULL)
     {
       free ((char *) work -> btypevec);
+      work->btypevec = NULL;
     }
   if (work -> ktypevec != NULL)
     {
       free ((char *) work -> ktypevec);
+      work->ktypevec = NULL;
     }
 }
 
@@ -1237,8 +1331,7 @@ delete_non_B_K_work_stuff (struct work_stuff *work)
       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[i]);
 
       free ((char*) work->tmpl_argvec);
       work->tmpl_argvec = NULL;
@@ -3583,7 +3676,10 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
                    string_delete (&temp);
                  }
                else
-                 break;
+                 {
+                   string_delete (&temp);
+                   break;
+                 }
              }
            else if (**mangled == 'Q')
              {
This page took 0.034547 seconds and 4 git commands to generate.