This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] D demangle: Include type modifiers in demangled function symbols


Like C++ const and volatile, in D mangled symbols can exist modifiers
that represent the const, immutable, inout and shared-ness of the
'this' parameter.

This information should be written out in the demangled symbol to show
that each variant has a unique identity.

---
libiberty/ChangeLog:

2015-05-09 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_parse_symbol): Emit the type modifier after the symbol.
    * testsuite/d-demangle-expected: Add coverage tests for all valid
    usages of functions symbols with type modifiers.
---
diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c
index bb481c0..9e6c46f 100644
--- a/libiberty/d-demangle.c
+++ b/libiberty/d-demangle.c
@@ -692,6 +692,44 @@ dlang_identifier (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 mangled;
+
+  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;
+    }
+}
+
 /* Extract the integer value from MANGLED and append it to DECL,
    where TYPE is the type it should be represented as.
    Return the remaining string on success or NULL on failure.  */
@@ -1104,6 +1142,41 @@ 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_type_modifier_p (const char *mangled)
+{
+  int i;
+
+  switch (*mangled)
+    {
+    case 'x': case 'y':
+      return 1;
+
+    case 'O':
+      mangled++;
+      i = dlang_type_modifier_p (mangled);
+      return i + 1;
+
+    case 'N':
+      mangled++;
+      if (*mangled == 'g')
+	{
+	  mangled++;
+	  i = dlang_type_modifier_p (mangled);
+	  return i + 2;
+	}
+
+    default:
+      break;
+    }
+
+  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)
 {
@@ -1116,9 +1189,9 @@ dlang_call_convention_p (const char *mangled)
       return 1;
 
     case 'M': /* Prefix for functions needing 'this' */
-      i = 1;
-      if (mangled[i] == 'x')
-	i++;
+      mangled++;
+      /* Skip over any type modifiers.  */
+      i = dlang_type_modifier_p (mangled);
 
       switch (mangled[i])
 	{
@@ -1147,11 +1220,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);
@@ -1170,6 +1248,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));
diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected
index 2aeacb8..358372a 100644
--- a/libiberty/testsuite/d-demangle-expected
+++ b/libiberty/testsuite/d-demangle-expected
@@ -753,6 +753,38 @@ 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
+#
 # Unittests
 #
 --format=dlang

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]