diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index ae3ede9..07e1135 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -1538,119 +1538,129 @@ pph_read_file (const char *filename)
 }
 
 
-/* Read the attributes for a FUNCTION_DECL FNDECL.  If FNDECL had
-   a body, mark it for expansion.  */
+/* Read from STREAM the body of tcc_declaration tree DECL.  */
 
 static void
-pph_in_function_decl (pph_stream *stream, tree fndecl)
+pph_in_tcc_declaration (pph_stream *stream, tree decl)
 {
-  DECL_INITIAL (fndecl) = pph_in_tree (stream);
-  pph_in_lang_specific (stream, fndecl);
-  DECL_SAVED_TREE (fndecl) = pph_in_tree (stream);
-  DECL_CHAIN (fndecl) = pph_in_tree (stream);
-}
-
+  pph_in_lang_specific (stream, decl);
+  DECL_INITIAL (decl) = pph_in_tree (stream);
 
+  /* The tree streamer only writes DECL_CHAIN for PARM_DECL nodes.  */
+  if (TREE_CODE (decl) == VAR_DECL
+      || TREE_CODE (decl) == FUNCTION_DECL)
+    DECL_CHAIN (decl) = pph_in_tree (stream);
 
-/* Read the body fields of EXPR from STREAM.  */
-
-static void
-pph_read_tree_body (pph_stream *stream, tree expr)
-{
-  struct lto_input_block *ib = stream->encoder.r.ib;
-  struct data_in *data_in = stream->encoder.r.data_in;
-
-  /* Read the language-independent parts of EXPR's body.  */
-  streamer_read_tree_body (ib, data_in, expr);
-
-  /* Read all the language-dependent fields.  */
-  switch (TREE_CODE (expr))
+  /* Handle some individual decl nodes.  */
+  switch (TREE_CODE (decl))
     {
-    /* TREES NEEDING EXTRA WORK */
-
-    /* tcc_declaration */
-
-    case DEBUG_EXPR_DECL:
-    case IMPORTED_DECL:
-    case LABEL_DECL:
-    case RESULT_DECL:
-      DECL_INITIAL (expr) = pph_in_tree (stream);
-      break;
-
-    case CONST_DECL:
-    case FIELD_DECL:
-    case NAMESPACE_DECL:
-    case PARM_DECL:
-    case USING_DECL:
-    case VAR_DECL:
-      /* FIXME pph: Should we merge DECL_INITIAL into lang_specific? */
-      DECL_INITIAL (expr) = pph_in_tree (stream);
-      pph_in_lang_specific (stream, expr);
-      /* DECL_CHAIN is handled by generic code, except for VAR_DECLs.  */
-      if (TREE_CODE (expr) == VAR_DECL)
-	DECL_CHAIN (expr) = pph_in_tree (stream);
-      break;
-
     case FUNCTION_DECL:
-      pph_in_function_decl (stream, expr);
+      DECL_SAVED_TREE (decl) = pph_in_tree (stream);
       break;
 
     case TYPE_DECL:
-      DECL_INITIAL (expr) = pph_in_tree (stream);
-      pph_in_lang_specific (stream, expr);
-      DECL_ORIGINAL_TYPE (expr) = pph_in_tree (stream);
+      DECL_ORIGINAL_TYPE (decl) = pph_in_tree (stream);
       break;
 
     case TEMPLATE_DECL:
-      DECL_INITIAL (expr) = pph_in_tree (stream);
-      pph_in_lang_specific (stream, expr);
-      DECL_TEMPLATE_RESULT (expr) = pph_in_tree (stream);
-      DECL_TEMPLATE_PARMS (expr) = pph_in_tree (stream);
-      DECL_CONTEXT (expr) = pph_in_tree (stream);
+      DECL_TEMPLATE_RESULT (decl) = pph_in_tree (stream);
+      DECL_TEMPLATE_PARMS (decl) = pph_in_tree (stream);
       break;
 
-    /* tcc_type */
-
-    case ARRAY_TYPE:
-    case BOOLEAN_TYPE:
-    case COMPLEX_TYPE:
-    case ENUMERAL_TYPE:
-    case FIXED_POINT_TYPE:
-    case FUNCTION_TYPE:
-    case INTEGER_TYPE:
-    case LANG_TYPE:
-    case METHOD_TYPE:
-    case NULLPTR_TYPE:
-    case OFFSET_TYPE:
-    case POINTER_TYPE:
-    case REAL_TYPE:
-    case REFERENCE_TYPE:
-    case VECTOR_TYPE:
-    case VOID_TYPE:
-      TYPE_LANG_SPECIFIC (expr) = pph_in_lang_type (stream);
+    default:
       break;
+    }
+}
 
-    case QUAL_UNION_TYPE:
-    case RECORD_TYPE:
-    case UNION_TYPE:
-      TYPE_LANG_SPECIFIC (expr) = pph_in_lang_type (stream);
-      TYPE_BINFO (expr) = pph_in_tree (stream);
-      break;
 
+/* Read from STREAM the body of tcc_type node TYPE.  */
+
+static void
+pph_in_tcc_type (pph_stream *stream, tree type)
+{
+  TYPE_LANG_SPECIFIC (type) = pph_in_lang_type (stream);
+  TYPE_POINTER_TO (type) = pph_in_tree (stream);
+  TYPE_REFERENCE_TO (type) = pph_in_tree (stream);
+  TYPE_NEXT_VARIANT (type) = pph_in_tree (stream);
+  /* FIXME pph - Streaming TYPE_CANONICAL generates many type comparison
+     failures.  Why?  */
+
+  /* The type values cache is built as constants are instantiated,
+     so we only stream it on the nodes that use it for
+     other purposes.  */
+  switch (TREE_CODE (type))
+    {
     case BOUND_TEMPLATE_TEMPLATE_PARM:
     case DECLTYPE_TYPE:
     case TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_TYPE_PARM:
     case TYPENAME_TYPE:
     case TYPEOF_TYPE:
-      TYPE_LANG_SPECIFIC (expr) = pph_in_lang_type (stream);
-      TYPE_CACHED_VALUES (expr) = pph_in_tree (stream);
-      /* Note that we are using TYPED_CACHED_VALUES for it access to 
-         the generic .values field of types. */
+      TYPE_VALUES_RAW (type) = pph_in_tree (stream);
       break;
 
-    /* tcc_statement */
+    default:
+      break;
+    }
+}
+
+
+/* Read the body fields of EXPR from STREAM.  */
+
+static void
+pph_read_tree_body (pph_stream *stream, tree expr)
+{
+  struct lto_input_block *ib = stream->encoder.r.ib;
+  struct data_in *data_in = stream->encoder.r.data_in;
+  bool handled_p;
+
+  /* Read the language-independent parts of EXPR's body.  */
+  streamer_read_tree_body (ib, data_in, expr);
+
+  /* Handle common tree code classes first.  */
+  handled_p = true;
+  switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+    {
+      case tcc_declaration:
+	pph_in_tcc_declaration (stream, expr);
+	break;
+
+      case tcc_type:
+	pph_in_tcc_type (stream, expr);
+	break;
+
+      case tcc_constant:
+	if (TREE_CODE (expr) == PTRMEM_CST)
+	  {
+	    pph_in_tree_common (stream, expr);
+	    PTRMEM_CST_MEMBER (expr) = pph_in_tree (stream);
+	  }
+	break;
 
+      case tcc_expression:
+      case tcc_unary:
+      case tcc_binary:
+      case tcc_vl_exp:
+      case tcc_reference:
+      case tcc_comparison:
+      case tcc_statement:
+	/* These tree classes are completely handled by the tree streamer.  */
+	break;
+
+      default:
+	handled_p = false;
+	break;
+    }
+
+  /* If we've already handled the tree, we are done.  */
+  if (handled_p)
+    return;
+
+  /* Only tcc_exceptional tree codes are left to handle.  */
+  gcc_assert (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_exceptional);
+
+  switch (TREE_CODE (expr))
+    {
     case STATEMENT_LIST:
       {
         HOST_WIDE_INT i, num_trees = pph_in_uint (stream);
@@ -1662,18 +1672,6 @@ pph_read_tree_body (pph_stream *stream, tree expr)
       }
       break;
 
-    /* tcc_expression */
-
-    /* tcc_unary */
-
-    /* tcc_vl_exp */
-
-    /* tcc_reference */
-
-    /* tcc_constant */
-
-    /* tcc_exceptional */
-
     case OVERLOAD:
       pph_in_tree_common (stream, expr);
       OVL_FUNCTION (expr) = pph_in_tree (stream);
@@ -1703,27 +1701,6 @@ pph_read_tree_body (pph_stream *stream, tree expr)
           = pph_in_qual_use_vec (stream);
       break;
 
-    case TEMPLATE_PARM_INDEX:
-      {
-        template_parm_index *p = TEMPLATE_PARM_INDEX_CAST (expr);
-        pph_in_tree_common (stream, expr);
-        p->index = pph_in_uint (stream);
-        p->level = pph_in_uint (stream);
-        p->orig_level = pph_in_uint (stream);
-        p->num_siblings = pph_in_uint (stream);
-        p->decl = pph_in_tree (stream);
-      }
-      break;
-
-    /* tcc_constant */
-
-    case PTRMEM_CST:
-      pph_in_tree_common (stream, expr);
-      PTRMEM_CST_MEMBER (expr) = pph_in_tree (stream);
-      break;
-
-    /* tcc_exceptional */
-
     case DEFAULT_ARG:
       pph_in_tree_common (stream, expr);
       DEFARG_TOKENS (expr) = pph_in_token_cache (stream);
@@ -1764,110 +1741,53 @@ pph_read_tree_body (pph_stream *stream, tree expr)
       }
       break;
 
+    case TREE_VEC:
+      /* TREE_VECs hold template argument lists.  */
+      NON_DEFAULT_TEMPLATE_ARGS_COUNT (expr) = pph_in_tree (stream);
+      break;
 
-    /* TREES ALREADY HANDLED */
-
-    /* tcc_declaration */
+    case PLACEHOLDER_EXPR:
+      TREE_TYPE (expr) = pph_in_tree (stream);
+      break;
 
-    case TRANSLATION_UNIT_DECL:
+    case TEMPLATE_PARM_INDEX:
+      {
+        template_parm_index *p = TEMPLATE_PARM_INDEX_CAST (expr);
+        pph_in_tree_common (stream, expr);
+        p->index = pph_in_uint (stream);
+        p->level = pph_in_uint (stream);
+        p->orig_level = pph_in_uint (stream);
+        p->num_siblings = pph_in_uint (stream);
+        p->decl = pph_in_tree (stream);
+      }
+      break;
 
-    /* tcc_exceptional */
+    case DEFERRED_NOEXCEPT:
+      DEFERRED_NOEXCEPT_PATTERN (expr) = pph_in_tree (stream);
+      DEFERRED_NOEXCEPT_ARGS (expr) = pph_in_tree (stream);
+      break;
 
-    case TREE_BINFO:
+    /* TREES ALREADY HANDLED */
+    case ERROR_MARK:
     case TREE_LIST:
-    case TREE_VEC:
-
+    case BLOCK:
+    case CONSTRUCTOR:
+    case SSA_NAME:
+    case TREE_BINFO:
       break;
 
-
     /* TREES UNIMPLEMENTED */
-
-    /* tcc_declaration */
-
-    /* tcc_type */
-
-    case TYPE_ARGUMENT_PACK:
-    case TYPE_PACK_EXPANSION:
-    case UNBOUND_CLASS_TEMPLATE:
-
-    /* tcc_statement */
-
-    case USING_STMT:
-    case TRY_BLOCK:
-    case EH_SPEC_BLOCK:
-    case HANDLER:
-    case CLEANUP_STMT:
-    case IF_STMT:
-    case FOR_STMT:
-    case RANGE_FOR_STMT:
-    case WHILE_STMT:
-    case DO_STMT:
-    case BREAK_STMT:
-    case CONTINUE_STMT:
-    case SWITCH_STMT:
-
-    /* tcc_expression */
-
-    case NEW_EXPR:
-    case VEC_NEW_EXPR:
-    case DELETE_EXPR:
-    case VEC_DELETE_EXPR:
-    case TYPE_EXPR:
-    case VEC_INIT_EXPR:
-    case THROW_EXPR:
-    case EMPTY_CLASS_EXPR:
-    case TEMPLATE_ID_EXPR:
-    case PSEUDO_DTOR_EXPR:
-    case MODOP_EXPR:
-    case DOTSTAR_EXPR:
-    case TYPEID_EXPR:
-    case NON_DEPENDENT_EXPR:
-    case CTOR_INITIALIZER:
-    case MUST_NOT_THROW_EXPR:
-    case EXPR_STMT:
-    case TAG_DEFN:
-    case OFFSETOF_EXPR:
-    case SIZEOF_EXPR:
-    case ARROW_EXPR:
-    case ALIGNOF_EXPR:
-    case AT_ENCODE_EXPR:
-    case STMT_EXPR:
-    case NONTYPE_ARGUMENT_PACK:
-    case EXPR_PACK_EXPANSION:
-
-    /* tcc_unary */
-
-    case CAST_EXPR:
-    case REINTERPRET_CAST_EXPR:
-    case CONST_CAST_EXPR:
-    case STATIC_CAST_EXPR:
-    case DYNAMIC_CAST_EXPR:
-    case NOEXCEPT_EXPR:
-    case UNARY_PLUS_EXPR:
-
-    /* tcc_reference */
-
-    case MEMBER_REF:
-    case OFFSET_REF:
-    case SCOPE_REF:
-
-    /* tcc_vl_exp */
-
-    case AGGR_INIT_EXPR:
-
-
-      if (flag_pph_untree)
-        fprintf (pph_logfile, "PPH: unimplemented tree node %s\n",
-                 tree_code_name[TREE_CODE (expr)]);
+    case OMP_CLAUSE:
+    case OPTIMIZATION_NODE:
+    case TARGET_OPTION_NODE:
+      fatal_error ("PPH: unimplemented tree node '%s'",
+		   tree_code_name[TREE_CODE (expr)]);
       break;
 
-
     /* TREES UNRECOGNIZED */
-
     default:
-      if (flag_pph_untree)
-        fprintf (pph_logfile, "PPH: unrecognized tree node %s\n",
-                 tree_code_name[TREE_CODE (expr)]);
+      fatal_error ("PPH: unrecognized tree node '%s'",
+                   tree_code_name[TREE_CODE (expr)]);
     }
 }
 
diff --git a/gcc/cp/pph-streamer-out.c b/gcc/cp/pph-streamer-out.c
index fe0758f..024de38 100644
--- a/gcc/cp/pph-streamer-out.c
+++ b/gcc/cp/pph-streamer-out.c
@@ -1374,128 +1374,135 @@ pph_write_file (pph_stream *stream)
 }
 
 
-/* Emit the fields of FUNCTION_DECL FNDECL to STREAM.  */
+/* Write to STREAM the body of tcc_declaration tree DECL.  */
 
 static void
-pph_out_function_decl (pph_stream *stream, tree fndecl)
+pph_out_tcc_declaration (pph_stream *stream, tree decl)
 {
-  /* Note that we do not output DECL_STRUCT_FUNCTION here.  This is
-     emitted at the end of the PPH file in pph_out_symtab.
-     This way, we will be able to re-instantiate them in the same
-     order when reading the image (the allocation of
-     DECL_STRUCT_FUNCTION has the side effect of generating function
-     sequence numbers (function.funcdef_no).  */
-  pph_out_tree_1 (stream, DECL_INITIAL (fndecl), 3);
-  pph_out_lang_specific (stream, fndecl);
-  pph_out_tree_1 (stream, DECL_SAVED_TREE (fndecl), 3);
-  pph_out_tree_1 (stream, DECL_CHAIN (fndecl), 3);
-}
-
-
-/* Write the body of EXPR to STREAM.  This writes out all fields not
-   written by the generic tree streaming routines.  */
-
-static void
-pph_write_tree_body (pph_stream *stream, tree expr)
-{
-  /* Write the language-independent parts of EXPR's body.  */
-  streamer_write_tree_body (stream->encoder.w.ob, expr, false);
+  pph_out_lang_specific (stream, decl);
+  pph_out_tree (stream, DECL_INITIAL (decl));
 
-  /* The following trees have language-dependent information that is
-     not written by the generic tree streaming routines.  Handle them
-     here.
+  /* The tree streamer only writes DECL_CHAIN for PARM_DECL nodes.  */
+  if (TREE_CODE (decl) == VAR_DECL
+      || TREE_CODE (decl) == FUNCTION_DECL)
+    pph_out_tree (stream, DECL_CHAIN (decl));
 
-     FIXME pph.  This could be handled using TS_* markers in
-     treestruct.def but those markers are not complete.  To fix this,
-     embed the TS_* directly in the tree node definitions in tree.def
-     and cp/cp-tree.def.  */
-  switch (TREE_CODE (expr))
+  /* Handle some individual decl nodes.  */
+  switch (TREE_CODE (decl))
     {
-    /* TREES NEEDING EXTRA WORK */
-
-    /* tcc_declaration */
-
-    case DEBUG_EXPR_DECL:
-    case IMPORTED_DECL:
-    case LABEL_DECL:
-    case RESULT_DECL:
-      pph_out_tree_1 (stream, DECL_INITIAL (expr), 3);
-      break;
-
-    case CONST_DECL:
-    case FIELD_DECL:
-    case NAMESPACE_DECL:
-    case PARM_DECL:
-    case USING_DECL:
-    case VAR_DECL:
-      /* FIXME pph: Should we merge DECL_INITIAL into lang_specific? */
-      pph_out_tree_1 (stream, DECL_INITIAL (expr), 3);
-      pph_out_lang_specific (stream, expr);
-      /* DECL_CHAIN is handled by generic code, except for VAR_DECLs.  */
-      if (TREE_CODE (expr) == VAR_DECL)
-	pph_out_tree_1 (stream, DECL_CHAIN (expr), 3);
-      break;
-
     case FUNCTION_DECL:
-      pph_out_function_decl (stream, expr);
+      /* Note that for FUNCTION_DECLs we do not output
+	 DECL_STRUCT_FUNCTION here.  This is emitted at the end of the
+	 PPH file in pph_out_symtab. This way, we will be able to
+	 re-instantiate them in the same order when reading the image
+	 (the allocation of DECL_STRUCT_FUNCTION has the side effect
+	 of generating function sequence numbers
+	 (function.funcdef_no).  */
+      pph_out_tree (stream, DECL_SAVED_TREE (decl));
       break;
 
     case TYPE_DECL:
-      pph_out_tree_1 (stream, DECL_INITIAL (expr), 3);
-      pph_out_lang_specific (stream, expr);
-      pph_out_tree_1 (stream, DECL_ORIGINAL_TYPE (expr), 3);
+      pph_out_tree (stream, DECL_ORIGINAL_TYPE (decl));
       break;
 
     case TEMPLATE_DECL:
-      pph_out_tree_1 (stream, DECL_INITIAL (expr), 3);
-      pph_out_lang_specific (stream, expr);
-      pph_out_tree_1 (stream, DECL_TEMPLATE_RESULT (expr), 3);
-      pph_out_tree_1 (stream, DECL_TEMPLATE_PARMS (expr), 3);
-      pph_out_tree_1 (stream, DECL_CONTEXT (expr), 3);
+      pph_out_tree (stream, DECL_TEMPLATE_RESULT (decl));
+      pph_out_tree (stream, DECL_TEMPLATE_PARMS (decl));
       break;
 
-    /* tcc_type */
-
-    case ARRAY_TYPE:
-    case BOOLEAN_TYPE:
-    case COMPLEX_TYPE:
-    case ENUMERAL_TYPE:
-    case FIXED_POINT_TYPE:
-    case FUNCTION_TYPE:
-    case INTEGER_TYPE:
-    case LANG_TYPE:
-    case METHOD_TYPE:
-    case NULLPTR_TYPE:
-    case OFFSET_TYPE:
-    case POINTER_TYPE:
-    case REAL_TYPE:
-    case REFERENCE_TYPE:
-    case VECTOR_TYPE:
-    case VOID_TYPE:
-      pph_out_lang_type (stream, expr);
+    default:
       break;
+    }
+}
 
-    case QUAL_UNION_TYPE:
-    case RECORD_TYPE:
-    case UNION_TYPE:
-      pph_out_lang_type (stream, expr);
-      pph_out_tree_1 (stream, TYPE_BINFO (expr), 3);
-      break;
 
+/* Write to STREAM the body of tcc_type node TYPE.  */
+
+static void
+pph_out_tcc_type (pph_stream *stream, tree type)
+{
+  pph_out_lang_type (stream, type);
+  pph_out_tree (stream, TYPE_POINTER_TO (type));
+  pph_out_tree (stream, TYPE_REFERENCE_TO (type));
+  pph_out_tree (stream, TYPE_NEXT_VARIANT (type));
+  /* FIXME pph - Streaming TYPE_CANONICAL generates many type comparison
+     failures.  Why?  */
+
+  /* The type values cache is built as constants are instantiated,
+     so we only stream it on the nodes that use it for
+     other purposes.  */
+  switch (TREE_CODE (type))
+    {
     case BOUND_TEMPLATE_TEMPLATE_PARM:
     case DECLTYPE_TYPE:
     case TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_TYPE_PARM:
     case TYPENAME_TYPE:
     case TYPEOF_TYPE:
-      pph_out_lang_type (stream, expr);
-      pph_out_tree_1 (stream, TYPE_CACHED_VALUES (expr), 3);
-      /* Note that we are using TYPED_CACHED_VALUES for it access to
-         the generic .values field of types. */
+      pph_out_tree (stream, TYPE_VALUES_RAW (type));
+      break;
+
+    default:
       break;
+    }
+}
+
+
+/* Write the body of EXPR to STREAM.  This writes out all fields not
+   written by the generic tree streaming routines.  */
 
-    /* tcc_statement */
+static void
+pph_write_tree_body (pph_stream *stream, tree expr)
+{
+  bool handled_p;
+
+  /* Write the language-independent parts of EXPR's body.  */
+  streamer_write_tree_body (stream->encoder.w.ob, expr, false);
+
+  /* Handle common tree code classes first.  */
+  handled_p = true;
+  switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+    {
+      case tcc_declaration:
+	pph_out_tcc_declaration (stream, expr);
+	break;
+
+      case tcc_type:
+	pph_out_tcc_type (stream, expr);
+	break;
+
+      case tcc_constant:
+	if (TREE_CODE (expr) == PTRMEM_CST)
+	  {
+	    pph_out_tree_common (stream, expr);
+	    pph_out_tree_1 (stream, PTRMEM_CST_MEMBER (expr), 3);
+	  }
+	break;
+
+      case tcc_expression:
+      case tcc_unary:
+      case tcc_binary:
+      case tcc_vl_exp:
+      case tcc_reference:
+      case tcc_comparison:
+      case tcc_statement:
+	/* These tree classes are completely handled by the tree streamer.  */
+	break;
+
+      default:
+	handled_p = false;
+	break;
+    }
 
+  /* If we've already handled the tree, we are done.  */
+  if (handled_p)
+    return;
+
+  /* Only tcc_exceptional tree codes are left to handle.  */
+  gcc_assert (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_exceptional);
+
+  switch (TREE_CODE (expr))
+    {
     case STATEMENT_LIST:
       {
         tree_stmt_iterator i;
@@ -1513,18 +1520,6 @@ pph_write_tree_body (pph_stream *stream, tree expr)
       }
       break;
 
-    /* tcc_expression */
-
-    /* tcc_unary */
-
-    /* tcc_vl_exp */
-
-    /* tcc_reference */
-
-    /* tcc_constant */
-
-    /* tcc_exceptional */
-
     case OVERLOAD:
       pph_out_tree_common (stream, expr);
       pph_out_tree_1 (stream, OVL_CURRENT (expr), 3);
@@ -1550,31 +1545,9 @@ pph_write_tree_body (pph_stream *stream, tree expr)
 
     case TEMPLATE_INFO:
       pph_out_tree_common (stream, expr);
-      pph_out_qual_use_vec (stream,
-          TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr));
-      break;
-
-    case TEMPLATE_PARM_INDEX:
-      {
-        template_parm_index *p = TEMPLATE_PARM_INDEX_CAST (expr);
-        pph_out_tree_common (stream, expr);
-        pph_out_uint (stream, p->index);
-        pph_out_uint (stream, p->level);
-        pph_out_uint (stream, p->orig_level);
-        pph_out_uint (stream, p->num_siblings);
-        pph_out_tree_1 (stream, p->decl, 3);
-      }
-      break;
-
-    /* tcc_constant */
-
-    case PTRMEM_CST:
-      pph_out_tree_common (stream, expr);
-      pph_out_tree_1 (stream, PTRMEM_CST_MEMBER (expr), 3);
+      pph_out_qual_use_vec (stream, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr));
       break;
 
-    /* tcc_exceptional */
-
     case DEFAULT_ARG:
       pph_out_tree_common (stream, expr);
       pph_out_token_cache (stream, DEFARG_TOKENS (expr));
@@ -1615,109 +1588,53 @@ pph_write_tree_body (pph_stream *stream, tree expr)
       }
       break;
 
+    case TREE_VEC:
+      /* TREE_VECs hold template argument lists.  */
+      pph_out_tree (stream, NON_DEFAULT_TEMPLATE_ARGS_COUNT (expr));
+      break;
 
-    /* TREES ALREADY HANDLED */
-
-    /* tcc_declaration */
+    case PLACEHOLDER_EXPR:
+      pph_out_tree (stream, TREE_TYPE (expr));
+      break;
 
-    case TRANSLATION_UNIT_DECL:
+    case TEMPLATE_PARM_INDEX:
+      {
+        template_parm_index *p = TEMPLATE_PARM_INDEX_CAST (expr);
+        pph_out_tree_common (stream, expr);
+        pph_out_uint (stream, p->index);
+        pph_out_uint (stream, p->level);
+        pph_out_uint (stream, p->orig_level);
+        pph_out_uint (stream, p->num_siblings);
+        pph_out_tree_1 (stream, p->decl, 3);
+      }
+      break;
 
-    /* tcc_exceptional */
+    case DEFERRED_NOEXCEPT:
+      pph_out_tree (stream, DEFERRED_NOEXCEPT_PATTERN (expr));
+      pph_out_tree (stream, DEFERRED_NOEXCEPT_ARGS (expr));
+      break;
 
-    case TREE_BINFO:
+    /* TREES ALREADY HANDLED */
+    case ERROR_MARK:
     case TREE_LIST:
-    case TREE_VEC:
-
+    case BLOCK:
+    case CONSTRUCTOR:
+    case SSA_NAME:
+    case TREE_BINFO:
       break;
 
     /* TREES UNIMPLEMENTED */
-
-    /* tcc_declaration */
-
-    /* tcc_type */
-
-    case TYPE_ARGUMENT_PACK:
-    case TYPE_PACK_EXPANSION:
-    case UNBOUND_CLASS_TEMPLATE:
-
-    /* tcc_statement */
-
-    case USING_STMT:
-    case TRY_BLOCK:
-    case EH_SPEC_BLOCK:
-    case HANDLER:
-    case CLEANUP_STMT:
-    case IF_STMT:
-    case FOR_STMT:
-    case RANGE_FOR_STMT:
-    case WHILE_STMT:
-    case DO_STMT:
-    case BREAK_STMT:
-    case CONTINUE_STMT:
-    case SWITCH_STMT:
-
-    /* tcc_expression */
-
-    case NEW_EXPR:
-    case VEC_NEW_EXPR:
-    case DELETE_EXPR:
-    case VEC_DELETE_EXPR:
-    case TYPE_EXPR:
-    case VEC_INIT_EXPR:
-    case THROW_EXPR:
-    case EMPTY_CLASS_EXPR:
-    case TEMPLATE_ID_EXPR:
-    case PSEUDO_DTOR_EXPR:
-    case MODOP_EXPR:
-    case DOTSTAR_EXPR:
-    case TYPEID_EXPR:
-    case NON_DEPENDENT_EXPR:
-    case CTOR_INITIALIZER:
-    case MUST_NOT_THROW_EXPR:
-    case EXPR_STMT:
-    case TAG_DEFN:
-    case OFFSETOF_EXPR:
-    case SIZEOF_EXPR:
-    case ARROW_EXPR:
-    case ALIGNOF_EXPR:
-    case AT_ENCODE_EXPR:
-    case STMT_EXPR:
-    case NONTYPE_ARGUMENT_PACK:
-    case EXPR_PACK_EXPANSION:
-
-    /* tcc_unary */
-
-    case CAST_EXPR:
-    case REINTERPRET_CAST_EXPR:
-    case CONST_CAST_EXPR:
-    case STATIC_CAST_EXPR:
-    case DYNAMIC_CAST_EXPR:
-    case NOEXCEPT_EXPR:
-    case UNARY_PLUS_EXPR:
-
-    /* tcc_reference */
-
-    case MEMBER_REF:
-    case OFFSET_REF:
-    case SCOPE_REF:
-
-    /* tcc_vl_exp */
-
-    case AGGR_INIT_EXPR:
-
-
-      if (flag_pph_untree)
-        fprintf (pph_logfile, "PPH: unimplemented tree node %s\n",
-                 tree_code_name[TREE_CODE (expr)]);
+    case OMP_CLAUSE:
+    case OPTIMIZATION_NODE:
+    case TARGET_OPTION_NODE:
+      fatal_error ("PPH: unimplemented tree node '%s'",
+		   tree_code_name[TREE_CODE (expr)]);
       break;
 
-
     /* TREES UNRECOGNIZED */
-
     default:
-      if (flag_pph_untree)
-        fprintf (pph_logfile, "PPH: unrecognized tree node %s\n",
-                 tree_code_name[TREE_CODE (expr)]);
+      fatal_error ("PPH: unrecognized tree node '%s'",
+                   tree_code_name[TREE_CODE (expr)]);
     }
 }
 
