d-demangle.c (dlang_type_modifiers): New function.
authorIain Buclaw <ibuclaw@gdcproject.org>
Sat, 16 May 2015 16:49:35 +0000 (16:49 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Sat, 16 May 2015 16:49:35 +0000 (16:49 +0000)
libiberty/ChangeLog:

2015-05-16  Iain Buclaw  <ibuclaw@gdcproject.org>

* d-demangle.c (dlang_type_modifiers): New function.
(dlang_type_modifier_p): New function.
(dlang_call_convention_p): Ignore any kind of type modifier.
(dlang_type): Handle and emit the type modifier after delegate types.
(dlang_parse_symbol): Handle and emit the type modifier after the symbol.
* testsuite/d-demangle-expected: Add coverage tests for all valid
usages of function symbols with type modifiers.

From-SVN: r223242

libiberty/ChangeLog
libiberty/d-demangle.c
libiberty/testsuite/d-demangle-expected

index 2d94e2bf44c0fb5ae76c7378887f063277013a08..3eac5226392fec18bb6021922de1a00d09ae6767 100644 (file)
@@ -1,3 +1,13 @@
+2015-05-16  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+       * d-demangle.c (dlang_type_modifiers): New function.
+       (dlang_type_modifier_p): New function.
+       (dlang_call_convention_p): Ignore any kind of type modifier.
+       (dlang_type): Handle and emit the type modifier after delegate types.
+       (dlang_parse_symbol): Handle and emit the type modifier after the symbol.
+       * testsuite/d-demangle-expected: Add coverage tests for all valid
+       usages of function symbols with type modifiers.
+
 2015-05-16  Iain Buclaw  <ibuclaw@gdcproject.org>
 
        * d-demangle.c (dlang_call_convention): Return NULL if have reached the
index 09984782e382631a88d7e89dfc47c369bdc37334..98e81606b586c3e8b3f34613782b60d947e38529 100644 (file)
@@ -215,6 +215,44 @@ dlang_call_convention (string *decl, const char *mangled)
   return mangled;
 }
 
+/* Extract the type modifiers from MANGLED and append them to DECL.
+   Returns the remaining signature on success or NULL on failure.  */
+static const char *
+dlang_type_modifiers (string *decl, const char *mangled)
+{
+  if (mangled == NULL || *mangled == '\0')
+    return NULL;
+
+  switch (*mangled)
+    {
+    case 'x': /* const */
+      mangled++;
+      string_append (decl, " const");
+      return mangled;
+    case 'y': /* immutable */
+      mangled++;
+      string_append (decl, " immutable");
+      return mangled;
+    case 'O': /* shared */
+      mangled++;
+      string_append (decl, " shared");
+      return dlang_type_modifiers (decl, mangled);
+    case 'N':
+      mangled++;
+      if (*mangled == 'g') /* wild */
+       {
+         mangled++;
+         string_append (decl, " inout");
+         return dlang_type_modifiers (decl, mangled);
+       }
+      else
+       return NULL;
+
+    default:
+      return mangled;
+    }
+}
+
 /* Demangle the D function attributes from MANGLED and append it to DECL.
    Return the remaining string on success or NULL on failure.  */
 static const char *
@@ -476,10 +514,22 @@ dlang_type (string *decl, const char *mangled)
       mangled++;
       return dlang_parse_symbol (decl, mangled);
     case 'D': /* delegate T */
+    {
+      string mods;
+      size_t szmods;
       mangled++;
+
+      string_init (&mods);
+      mangled = dlang_type_modifiers (&mods, mangled);
+      szmods = string_length (&mods);
+
       mangled = dlang_function_type (decl, mangled);
       string_append (decl, "delegate");
+      string_appendn (decl, mods.b, szmods);
+
+      string_delete (&mods);
       return mangled;
+    }
     case 'B': /* tuple T */
       mangled++;
       return dlang_parse_tuple (decl, mangled);
@@ -1135,28 +1185,54 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
   return mangled;
 }
 
+/* Extract the type modifiers from MANGLED and return the string
+   length that it consumes in MANGLED on success or 0 on failure.  */
 static int
-dlang_call_convention_p (const char *mangled)
+dlang_type_modifier_p (const char *mangled)
 {
-  size_t i;
+  int i;
 
   switch (*mangled)
     {
-    case 'F': case 'U': case 'V':
-    case 'W': case 'R':
+    case 'x': case 'y':
       return 1;
 
-    case 'M': /* Prefix for functions needing 'this' */
-      i = 1;
-      if (mangled[i] == 'x')
-       i++;
+    case 'O':
+      mangled++;
+      i = dlang_type_modifier_p (mangled);
+      return i + 1;
 
-      switch (mangled[i])
+    case 'N':
+      mangled++;
+      if (*mangled == 'g')
        {
-       case 'F': case 'U': case 'V':
-       case 'W': case 'R':
-         return 1;
+         mangled++;
+         i = dlang_type_modifier_p (mangled);
+         return i + 2;
        }
+    }
+
+  return 0;
+}
+
+/* Extract the function calling convention from MANGLED and
+   return 1 on success or 0 on failure.  */
+static int
+dlang_call_convention_p (const char *mangled)
+{
+  /* Prefix for functions needing 'this' */
+  if (*mangled == 'M')
+    {
+      mangled++;
+      /* Also skip over any type modifiers.  */
+      mangled += dlang_type_modifier_p (mangled);
+    }
+
+  switch (*mangled)
+    {
+    case 'F': case 'U': case 'V':
+    case 'W': case 'R':
+      return 1;
 
     default:
       return 0;
@@ -1178,11 +1254,16 @@ dlang_parse_symbol (string *decl, const char *mangled)
 
       if (mangled && dlang_call_convention_p (mangled))
        {
+         string mods;
          int saved;
 
          /* Skip over 'this' parameter.  */
          if (*mangled == 'M')
-           mangled += (mangled[1] == 'x') ? 2 : 1;
+           mangled++;
+
+         /* Save the type modifiers for appending at the end.  */
+         string_init (&mods);
+         mangled = dlang_type_modifiers (&mods, mangled);
 
          /* Skip over calling convention and attributes in qualified name.  */
          saved = string_length (decl);
@@ -1201,6 +1282,10 @@ dlang_parse_symbol (string *decl, const char *mangled)
              mangled = dlang_type (decl, mangled);
              string_setlength (decl, saved);
            }
+
+         /* Add any const/immutable/shared modifier. */
+         string_appendn (decl, mods.b, string_length (&mods));
+         string_delete (&mods);
        }
     }
   while (mangled && ISDIGIT (*mangled));
index b023f6d5d79ddd252bb56d15d94de9de3fafefea..80445066e7253eda40858b337998a1d6ad51a75e 100644 (file)
@@ -753,6 +753,70 @@ demangle.test!(demangle.S(1, 2))
 _D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv
 demangle.test!(demangle.S(1, "abc"))
 #
+--format=dlang
+_D8demangle4testMxFZv
+demangle.test() const
+#
+--format=dlang
+_D8demangle4testMyFZv
+demangle.test() immutable
+#
+--format=dlang
+_D8demangle4testMNgFZv
+demangle.test() inout
+#
+--format=dlang
+_D8demangle4testMNgxFZv
+demangle.test() inout const
+#
+--format=dlang
+_D8demangle4testMOFZv
+demangle.test() shared
+#
+--format=dlang
+_D8demangle4testMOxFZv
+demangle.test() shared const
+#
+--format=dlang
+_D8demangle4testMONgFZv
+demangle.test() shared inout
+#
+--format=dlang
+_D8demangle4testMONgxFZv
+demangle.test() shared inout const
+#
+--format=dlang
+_D8demangle4testFDxFZaZv
+demangle.test(char() delegate const)
+#
+--format=dlang
+_D8demangle4testFDyFZaZv
+demangle.test(char() delegate immutable)
+#
+--format=dlang
+_D8demangle4testFDNgFZaZv
+demangle.test(char() delegate inout)
+#
+--format=dlang
+_D8demangle4testFDNgxFZaZv
+demangle.test(char() delegate inout const)
+#
+--format=dlang
+_D8demangle4testFDOFZaZv
+demangle.test(char() delegate shared)
+#
+--format=dlang
+_D8demangle4testFDOxFZaZv
+demangle.test(char() delegate shared const)
+#
+--format=dlang
+_D8demangle4testFDONgFZaZv
+demangle.test(char() delegate shared inout)
+#
+--format=dlang
+_D8demangle4testFDONgxFZaZv
+demangle.test(char() delegate shared inout const)
+#
 # Unittests
 #
 --format=dlang