diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9c27cd04b8542c0bbbbe35c9f4e2d928ca4fc7f8..4b33059287f92cdcaa9a859659086bff60fe96a6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	PR c++/35319
+	* mangle.c (write_builtin_type): Add mangling for decimal floating 
+	point and fixed point types.
+	(write_type): Pass FIXED_POINT_TYPE along.
+
 2008-12-09  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/37971
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index c0282d8ade51bd7cb02ffaad93767be24af02baf..36b984e321407103d6e142102a76e24169365261 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1598,6 +1598,7 @@ write_type (tree type)
 	    case BOOLEAN_TYPE:
 	    case INTEGER_TYPE:  /* Includes wchar_t.  */
 	    case REAL_TYPE:
+	    case FIXED_POINT_TYPE:
 	      {
 		/* If this is a typedef, TYPE may not be one of
 		   the standard builtin type nodes, but an alias of one.  Use
@@ -1852,6 +1853,59 @@ write_builtin_type (tree type)
 	gcc_unreachable ();
       break;
 
+    case FIXED_POINT_TYPE:
+      write_string ("DF");
+      if (GET_MODE_IBIT (TYPE_MODE (type)) > 0)
+	write_unsigned_number (GET_MODE_IBIT (TYPE_MODE (type)));
+      if (type == fract_type_node
+	  || type == sat_fract_type_node
+	  || type == accum_type_node
+	  || type == sat_accum_type_node)
+	write_char ('i');
+      else if (type == unsigned_fract_type_node
+	       || type == sat_unsigned_fract_type_node
+	       || type == unsigned_accum_type_node
+	       || type == sat_unsigned_accum_type_node)
+	write_char ('j');
+      else if (type == short_fract_type_node
+	       || type == sat_short_fract_type_node
+	       || type == short_accum_type_node
+	       || type == sat_short_accum_type_node)
+	write_char ('s');
+      else if (type == unsigned_short_fract_type_node
+	       || type == sat_unsigned_short_fract_type_node
+	       || type == unsigned_short_accum_type_node
+	       || type == sat_unsigned_short_accum_type_node)
+	write_char ('t');
+      else if (type == long_fract_type_node
+	       || type == sat_long_fract_type_node
+	       || type == long_accum_type_node
+	       || type == sat_long_accum_type_node)
+	write_char ('l');
+      else if (type == unsigned_long_fract_type_node
+	       || type == sat_unsigned_long_fract_type_node
+	       || type == unsigned_long_accum_type_node
+	       || type == sat_unsigned_long_accum_type_node)
+	write_char ('m');
+      else if (type == long_long_fract_type_node
+	       || type == sat_long_long_fract_type_node
+	       || type == long_long_accum_type_node
+	       || type == sat_long_long_accum_type_node)
+	write_char ('x');
+      else if (type == unsigned_long_long_fract_type_node
+	       || type == sat_unsigned_long_long_fract_type_node
+	       || type == unsigned_long_long_accum_type_node
+	       || type == sat_unsigned_long_long_accum_type_node)
+	write_char ('y');
+      else
+	sorry ("mangling unknown fixed point type");
+      write_unsigned_number (GET_MODE_FBIT (TYPE_MODE (type)));
+      if (TYPE_SATURATING (type))
+	write_char ('s');
+      else
+	write_char ('n');
+      break;
+
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 659a5bf24e0dfa69dc1fb819d4220753d9d2c40f..f8a447f32420a72bed70960b60948ed94a999f88 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	PR c++/35319
+	* g++.dg/ext/fixed2.C: New test.
+
 2008-12-10  Daniel Berlin  <dberlin@dberlin.org>
 
 	PR tree-optimization/36792
diff --git a/gcc/testsuite/g++.dg/ext/fixed2.C b/gcc/testsuite/g++.dg/ext/fixed2.C
new file mode 100644
index 0000000000000000000000000000000000000000..a4766eb794cf619be12e7408f859ba0671098b30
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/fixed2.C
@@ -0,0 +1,7 @@
+// PR c++/35319
+// { dg-options "" }
+
+void foo()
+{
+  throw 0r;
+}
diff --git a/include/ChangeLog b/include/ChangeLog
index 768fb440033ee3e7cefbe75265354820a571c37b..a07e075f713420733eb774353a81498b2b797582 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	* demangle.h (enum demangle_component_type): Add 
+	DEMANGLE_COMPONENT_FIXED_TYPE.
+
 2008-11-19  Bob Wilson  <bob.wilson@acm.org>
 	
 	* xtensa-config.h (XCHAL_HAVE_MUL16, XCHAL_HAVE_MUL32, XCHAL_HAVE_DIV32)
diff --git a/include/demangle.h b/include/demangle.h
index 0ea639d62ba370f36e44b30835a0f2afb0ae41c7..28c69f5e78c4e291bf17a8bf2ed7b4d5984c987a 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -319,6 +319,8 @@ enum demangle_component_type
      and the right subtree is the member type.  CV-qualifiers appear
      on the latter.  */
   DEMANGLE_COMPONENT_PTRMEM_TYPE,
+  /* A fixed-point type.  */
+  DEMANGLE_COMPONENT_FIXED_TYPE,
   /* An argument list.  The left subtree is the current argument, and
      the right subtree is either NULL or another ARGLIST node.  */
   DEMANGLE_COMPONENT_ARGLIST,
@@ -419,6 +421,17 @@ struct demangle_component
       struct demangle_component *name;
     } s_extended_operator;
 
+    /* For DEMANGLE_COMPONENT_FIXED_TYPE.  */
+    struct
+    {
+      /* The length, indicated by a C integer type name.  */
+      struct demangle_component *length;
+      /* _Accum or _Fract?  */
+      short accum;
+      /* Saturating or not?  */
+      short sat;
+    } s_fixed;
+
     /* For DEMANGLE_COMPONENT_CTOR.  */
     struct
     {
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index fd9d30002176070fbb1d3fdb7c953ca78f1ece26..a6721bf906d81e91531520e93d25288e6ab28fe4 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	* cp-demangle.c (cplus_demangle_type): Support fixed-point types.
+	(d_print_comp, d_dump): Likewise.
+
 2008-10-22  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* Makefile.in (CPPFLAGS): Define.
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 3fa5f1f21d3b2e30e2a6df7e3f01df7e69451bd6..de0d9f7610eaea73ad937ca0e41e828348f25c46 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -621,6 +621,9 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
       printf ("pointer to member type\n");
       break;
+    case DEMANGLE_COMPONENT_FIXED_TYPE:
+      printf ("fixed-point type\n");
+      break;
     case DEMANGLE_COMPONENT_ARGLIST:
       printf ("argument list\n");
       break;
@@ -2115,6 +2118,19 @@ cplus_demangle_type (struct d_info *di)
 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
 	  di->expansion += ret->u.s_builtin.type->len;
 	  break;
+
+	case 'F':
+	  /* Fixed point types. DF<int bits><length><fract bits><sat>  */
+	  ret = d_make_empty (di);
+	  ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
+	  if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
+	    /* For demangling we don't care about the bits.  */
+	    d_number (di);
+	  ret->u.s_fixed.length = cplus_demangle_type (di);
+	  d_number (di);
+	  peek = d_next_char (di);
+	  ret->u.s_fixed.sat = (peek == 's');
+	  break;
 	}
       break;
 
@@ -3725,6 +3741,22 @@ d_print_comp (struct d_print_info *dpi,
 	return;
       }
 
+    case DEMANGLE_COMPONENT_FIXED_TYPE:
+      if (dc->u.s_fixed.sat)
+	d_append_string (dpi, "_Sat ");
+      /* Don't print "int _Accum".  */
+      if (dc->u.s_fixed.length->u.s_builtin.type
+	  != &cplus_demangle_builtin_types['i'-'a'])
+	{
+	  d_print_comp (dpi, dc->u.s_fixed.length);
+	  d_append_char (dpi, ' ');
+	}
+      if (dc->u.s_fixed.accum)
+	d_append_string (dpi, "_Accum");
+      else
+	d_append_string (dpi, "_Fract");
+      return;
+
     case DEMANGLE_COMPONENT_ARGLIST:
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
       if (d_left (dc) != NULL)