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
