This patch makes tracing more robust. It attempts to use type dumping where possible, use the PPH merge name where possible, and otherwise use "?". It protects protecting existing type dump machinery against some unexpected nulls. It changes tree streaming to write decl minimal fields first, so that they can be used while reading other fields. The patch adds some new tests for the upcoming type merging. Tested on x64. Index: gcc/testsuite/ChangeLog.pph 2012-02-01 Lawrence Crowl <crowl@google.com> * g++.dg/pph/c0struct.h: Rename to c0struct2.h. * g++.dg/pph/c0struct1.h: New. Has no typedefs. * g++.dg/pph/c1struct.cc: Rename to c1struct2.cc. * g++.dg/pph/c1struct1.cc: New. Has no typedefs. * g++.dg/pph/x0struct0.h: Rename to x0struct2.h. * g++.dg/pph/x0struct1.h: New. Has no typedefs. * g++.dg/pph/x1struct2.h: Rename to x1struct3.h. * g++.dg/pph/x1struct1.h: Rename to x1struct2.h. * g++.dg/pph/x1struct1.h: New. Has no typedefs. * g++.dg/pph/x2struct2.cc: Rename to x2struct3.cc. * g++.dg/pph/x2struct1.cc: Rename to x2struct2.cc. * g++.dg/pph/x2struct1.cc: New. Has no typedefs. Index: gcc/cp/ChangeLog.pph 2012-02-01 Lawrence Crowl <crowl@google.com> * pph-streamer.h (pph_trace_tree): Add name parameter. Adjust callers to match. * pph-core.c (pph_trace_tree): Add name parameter to override pretty-printing the tree. * error.c (dump_type): Protect against null TYPE_NAME. (dump_aggr_type): Factor out test for template. (is_template): New. Protect against null DECL_TEMPLATE_PARMS. * pph-out.c (pph_out_merge_body_namespace_decl): Factor out assert for mergable trees into separate cases. Merging of types is currently unexpected and disabled. * pph-in.c (pph_in_merge_key_namespace_decl): Remove redundant assert for mergable trees. (pph_in_merge_key_namespace_decl): Factor out assert for mergable trees into separate cases. Merging of types is currently unexpected and disabled. Index: gcc/ChangeLog.pph 2012-02-01 Lawrence Crowl <crowl@google.com> * tree-streamer-out.c (streamer_write_tree_body): Write decl minimal fields first, so that they can be used when reading other fields. * tree-streamer-in.c (streamer_write_tree_body): Read decl minimal fields first, so that they can be used when reading other fields. Index: gcc/testsuite/g++.dg/pph/c0struct2.h =================================================================== --- gcc/testsuite/g++.dg/pph/c0struct2.h (revision 183736) +++ gcc/testsuite/g++.dg/pph/c0struct2.h (working copy) @@ -1,5 +1,5 @@ -#ifndef C0STRUCT_H -#define C0STRUCT_H +#ifndef C0STRUCT2_H +#define C0STRUCT2_H typedef int type; type gbl = 1; struct B { Index: gcc/testsuite/g++.dg/pph/x0struct1.h =================================================================== --- gcc/testsuite/g++.dg/pph/x0struct1.h (revision 0) +++ gcc/testsuite/g++.dg/pph/x0struct1.h (revision 0) @@ -0,0 +1,5 @@ +#ifndef X0STRUCT1_H +#define X0STRUCT1_H +struct B { +}; +#endif Index: gcc/testsuite/g++.dg/pph/c0struct.h =================================================================== --- gcc/testsuite/g++.dg/pph/c0struct.h (revision 183805) +++ gcc/testsuite/g++.dg/pph/c0struct.h (working copy) @@ -1,9 +0,0 @@ -#ifndef C0STRUCT_H -#define C0STRUCT_H -typedef int type; -type gbl = 1; -struct B { - type fld; -}; -typedef B thing; -#endif Index: gcc/testsuite/g++.dg/pph/x0struct2.h =================================================================== --- gcc/testsuite/g++.dg/pph/x0struct2.h (revision 183736) +++ gcc/testsuite/g++.dg/pph/x0struct2.h (working copy) @@ -1,5 +1,5 @@ -#ifndef X0STRUCT0_H -#define X0STRUCT0_H +#ifndef X0STRUCT2_H +#define X0STRUCT2_H typedef int type; struct B { }; Index: gcc/testsuite/g++.dg/pph/c1struct1.cc =================================================================== --- gcc/testsuite/g++.dg/pph/c1struct1.cc (revision 0) +++ gcc/testsuite/g++.dg/pph/c1struct1.cc (revision 0) @@ -0,0 +1,4 @@ +#include "c0struct1.h" + +B var1; +B var2 = { 3 }; Index: gcc/testsuite/g++.dg/pph/x2struct1.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x2struct1.cc (revision 183805) +++ gcc/testsuite/g++.dg/pph/x2struct1.cc (working copy) @@ -1,10 +1,9 @@ #include "x1struct1.h" -type D::method() +int D::method() { static int x = 2; return fld + mbr; } -type D::mbr = 4; -typedef D D2; -D2 var1; -D2 var2 = var1; +int D::mbr = 4; +D var1; +D var2 = var1; Index: gcc/testsuite/g++.dg/pph/c1struct.cc =================================================================== --- gcc/testsuite/g++.dg/pph/c1struct.cc (revision 183805) +++ gcc/testsuite/g++.dg/pph/c1struct.cc (working copy) @@ -1,4 +0,0 @@ -#include "c0struct.h" - -thing var1; -thing var2 = { 3 }; Index: gcc/testsuite/g++.dg/pph/c1struct2.cc =================================================================== --- gcc/testsuite/g++.dg/pph/c1struct2.cc (revision 183736) +++ gcc/testsuite/g++.dg/pph/c1struct2.cc (working copy) @@ -1,4 +1,4 @@ -#include "c0struct.h" +#include "c0struct2.h" thing var1; thing var2 = { 3 }; Index: gcc/testsuite/g++.dg/pph/x1struct1.h =================================================================== --- gcc/testsuite/g++.dg/pph/x1struct1.h (revision 183805) +++ gcc/testsuite/g++.dg/pph/x1struct1.h (working copy) @@ -1,11 +1,11 @@ #ifndef X1STRUCT1_H #define X1STRUCT1_H -#include "x0struct0.h" -struct D : public thing { - type method(); - type another() +#include "x0struct1.h" +struct D : public B { + int method(); + int another() { return fld + mbr; } - type fld; - static type mbr; + int fld; + static int mbr; }; #endif Index: gcc/testsuite/g++.dg/pph/x2struct2.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x2struct2.cc (revision 183805) +++ gcc/testsuite/g++.dg/pph/x2struct2.cc (working copy) @@ -2,7 +2,7 @@ type D::method() { static int x = 2; - return fld + mbr + gbl; } + return fld + mbr; } type D::mbr = 4; typedef D D2; Index: gcc/testsuite/g++.dg/pph/x1struct2.h =================================================================== --- gcc/testsuite/g++.dg/pph/x1struct2.h (revision 183736) +++ gcc/testsuite/g++.dg/pph/x1struct2.h (working copy) @@ -1,6 +1,6 @@ -#ifndef X1STRUCT1_H -#define X1STRUCT1_H -#include "x0struct0.h" +#ifndef X1STRUCT2_H +#define X1STRUCT2_H +#include "x0struct2.h" struct D : public thing { type method(); type another() Index: gcc/testsuite/g++.dg/pph/x2struct3.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x2struct3.cc (revision 0) +++ gcc/testsuite/g++.dg/pph/x2struct3.cc (revision 0) @@ -0,0 +1,10 @@ +#include "x1struct3.h" + +type D::method() +{ static int x = 2; + return fld + mbr + gbl; } + +type D::mbr = 4; +typedef D D2; +D2 var1; +D2 var2 = var1; Index: gcc/testsuite/g++.dg/pph/x1struct3.h =================================================================== --- gcc/testsuite/g++.dg/pph/x1struct3.h (revision 183736) +++ gcc/testsuite/g++.dg/pph/x1struct3.h (working copy) @@ -1,6 +1,6 @@ #ifndef X1STRUCT_H #define X1STRUCT_H -#include "c0struct.h" +#include "c0struct2.h" struct D : thing { type method(); type another() Index: gcc/testsuite/g++.dg/pph/c0struct1.h =================================================================== --- gcc/testsuite/g++.dg/pph/c0struct1.h (revision 0) +++ gcc/testsuite/g++.dg/pph/c0struct1.h (revision 0) @@ -0,0 +1,7 @@ +#ifndef C0STRUCT1_H +#define C0STRUCT1_H +int gbl = 1; +struct B { + int fld; +}; +#endif Index: gcc/testsuite/g++.dg/pph/x0struct0.h =================================================================== --- gcc/testsuite/g++.dg/pph/x0struct0.h (revision 183805) +++ gcc/testsuite/g++.dg/pph/x0struct0.h (working copy) @@ -1,7 +0,0 @@ -#ifndef X0STRUCT0_H -#define X0STRUCT0_H -typedef int type; -struct B { -}; -typedef B thing; -#endif Index: gcc/cp/pph-core.c =================================================================== --- gcc/cp/pph-core.c (revision 183805) +++ gcc/cp/pph-core.c (working copy) @@ -364,7 +364,8 @@ pph_trace_marker (enum pph_record_marker /* Print tracing information for a possibly MERGEABLE tree T. */ void -pph_trace_tree (tree t, enum pph_trace_end end, enum pph_trace_kind kind) +pph_trace_tree (tree t, const char *name, + enum pph_trace_end end, enum pph_trace_kind kind) { char end_char, kind_char, decl_char; bool is_merge, is_decl; @@ -390,7 +391,7 @@ pph_trace_tree (tree t, enum pph_trace_e break; case pph_trace_mutate: kind_char = '='; - is_merge = false; + is_merge = true; break; case pph_trace_normal: kind_char = '.'; @@ -421,9 +422,9 @@ pph_trace_tree (tree t, enum pph_trace_e if (emit) { fprintf (pph_logfile, "PPH: %c%c%c ", end_char, kind_char, decl_char); - if (kind == pph_trace_unmerged_key || end == pph_trace_front) - fprintf (pph_logfile, "%s -------\n", - pph_tree_code_text (TREE_CODE (t))); + if (name) + fprintf (pph_logfile, "%p %s %s\n", (void*)t, + pph_tree_code_text (TREE_CODE (t)), name); else pph_dump_tree_name (pph_logfile, t, 0); } Index: gcc/cp/error.c =================================================================== --- gcc/cp/error.c (revision 183805) +++ gcc/cp/error.c (working copy) @@ -463,12 +463,21 @@ dump_type (tree t, int flags) break; case TEMPLATE_TYPE_PARM: - pp_cxx_cv_qualifier_seq (cxx_pp, t); - if (TYPE_IDENTIFIER (t)) - pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t)); - else - pp_cxx_canonical_template_parameter - (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t)); + { + tree decl = TYPE_NAME (t); + pp_cxx_cv_qualifier_seq (cxx_pp, t); + if (decl) + { + tree ident = DECL_NAME (decl); + if (ident) + pp_cxx_tree_identifier (cxx_pp, ident); + else + pp_cxx_canonical_template_parameter + (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t)); + } + else + pp_cxx_ws_string (cxx_pp, "<nameless>"); + } break; /* This is not always necessary for pointers and such, but doing this @@ -593,6 +602,27 @@ class_key_or_enum_as_string (tree t) return "struct"; } + +/* Determine if a tree T is a template. */ + +static bool is_template (tree t) +{ + tree ti_tmpl, parms; + if (TREE_CODE (t) == ENUMERAL_TYPE) + return false; + if (!TYPE_LANG_SPECIFIC (t)) + return false; + if (!CLASSTYPE_TEMPLATE_INFO (t)) + return false; + ti_tmpl = CLASSTYPE_TI_TEMPLATE (t); + if (TREE_CODE (ti_tmpl) != TEMPLATE_DECL) + return true; + parms = DECL_TEMPLATE_PARMS (ti_tmpl); + if (parms) + return PRIMARY_TEMPLATE_P (ti_tmpl); + return false; +} + /* Print out a class declaration T under the control of FLAGS, in the form `class foo'. */ @@ -629,10 +659,7 @@ dump_aggr_type (tree t, int flags) typdef = 0; } - tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE - && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t) - && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL - || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))); + tmplate = !typdef && is_template (t); if (! (flags & TFF_UNQUALIFIED_NAME)) dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE); Index: gcc/cp/pph-out.c =================================================================== --- gcc/cp/pph-out.c (revision 183805) +++ gcc/cp/pph-out.c (working copy) @@ -2290,7 +2290,7 @@ pph_out_merge_key_namespace_decl (pph_st pph_out_merge_name (stream, decl); if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_front, pph_trace_key_out); + pph_trace_tree (decl, NULL, pph_trace_front, pph_trace_key_out); pph_out_tree (stream, DECL_NAME (decl)); @@ -2302,7 +2302,7 @@ pph_out_merge_key_namespace_decl (pph_st pph_out_merge_key_binding_level (stream, NAMESPACE_LEVEL (decl)); if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_back, pph_trace_key_out); + pph_trace_tree (decl, NULL, pph_trace_back, pph_trace_key_out); } @@ -2319,7 +2319,7 @@ pph_out_merge_body_namespace_decl (pph_s pph_out_tree_header (stream, decl); if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_front, pph_trace_merge_body); + pph_trace_tree (decl, NULL, pph_trace_front, pph_trace_merge_body); /* If EXPR is a namespace alias, it will not have an associated binding. In that case, tell the reader not to bother with it. */ @@ -2329,7 +2329,7 @@ pph_out_merge_body_namespace_decl (pph_s pph_out_merge_body_binding_level (stream, NAMESPACE_LEVEL (decl)); if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_back, pph_trace_merge_body); + pph_trace_tree (decl, NULL, pph_trace_back, pph_trace_merge_body); } @@ -2338,40 +2338,30 @@ pph_out_merge_body_namespace_decl (pph_s static void pph_out_merge_key_tree (pph_stream *stream, tree expr) { - gcc_assert (pph_tree_is_mergeable (expr)); - if (pph_out_start_merge_key_tree_record (stream, expr)) return; if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_front, pph_trace_key_out); + pph_trace_tree (expr, NULL, pph_trace_front, pph_trace_key_out); /* Write merge key information. This includes EXPR's header (needed - to re-allocate EXPR in the reader) and the merge key, used to - lookup EXPR in the reader's context and merge if necessary. */ + to re-allocate EXPR in the reader). */ pph_out_tree_header (stream, expr); - pph_out_merge_name (stream, expr); + if (DECL_P (expr)) { -#if 0 -/* FIXME pph: Distable tree merging for the moment. */ - else if (TREE_CODE (expr) == TYPE_DECL) - pph_out_merge_key_tree (stream, TREE_TYPE (expr)); + /* Write the merge name, used to lookup EXPR in the reader's context + and merge if necessary. */ + pph_out_merge_name (stream, expr); } - else if (CLASS_TYPE_P (expr)) + else { - unsigned filter = PPHF_NO_XREFS | PPHF_NO_PREFS | PPHF_NO_BUILTINS; - pph_out_merge_key_chain (stream, TYPE_FIELDS (expr), filter); - pph_out_merge_key_chain (stream, TYPE_METHODS (expr), filter); - /* FIXME pph: Nested types are broken. - pph_out_binding_table (stream, CLASSTYPE_NESTED_UTDS (expr)); - pph_out_merge_key_chain (stream, CLASSTYPE_DECL_LIST (expr), filter); - */ -#endif + gcc_assert (TYPE_P (expr)); + gcc_assert (false); } if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_back, pph_trace_key_out); + pph_trace_tree (expr, NULL, pph_trace_back, pph_trace_key_out); } @@ -2411,7 +2401,7 @@ pph_out_tree (pph_stream *stream, tree e } if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_front, + pph_trace_tree (expr, NULL, pph_trace_front, marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate : pph_trace_normal); @@ -2443,7 +2433,7 @@ pph_out_tree (pph_stream *stream, tree e gcc_unreachable (); if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_back, + pph_trace_tree (expr, NULL, pph_trace_back, marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate : pph_trace_normal); Index: gcc/cp/pph-streamer.h =================================================================== --- gcc/cp/pph-streamer.h (revision 183805) +++ gcc/cp/pph-streamer.h (working copy) @@ -260,7 +260,8 @@ pph_stream *pph_stream_open (const char void pph_stream_close (pph_stream *); void pph_stream_close_no_flush (pph_stream *); void pph_trace_marker (enum pph_record_marker marker, enum pph_tag tag); -void pph_trace_tree (tree, enum pph_trace_end, enum pph_trace_kind); +void pph_trace_tree (tree, const char *, + enum pph_trace_end, enum pph_trace_kind); pph_cache_entry *pph_cache_insert_at (pph_cache *, void *, unsigned, enum pph_tag); pph_cache_entry *pph_cache_lookup (pph_cache *, void *, unsigned *, Index: gcc/cp/pph-in.c =================================================================== --- gcc/cp/pph-in.c (revision 183805) +++ gcc/cp/pph-in.c (working copy) @@ -2281,11 +2281,9 @@ pph_in_merge_key_namespace_decl (pph_str gcc_assert (decl == NULL || TREE_CODE (decl) == NAMESPACE_DECL); read_decl = pph_in_tree_header (stream, &fully_read_p); - gcc_assert (!fully_read_p && pph_tree_is_mergeable (read_decl)); + gcc_assert (!fully_read_p && TREE_CODE (read_decl) == NAMESPACE_DECL); name = pph_in_string (stream); - gcc_assert (TREE_CODE (read_decl) == NAMESPACE_DECL); - if (!decl) { /* The record is new, so we need to link it in. */ @@ -2303,7 +2301,7 @@ pph_in_merge_key_namespace_decl (pph_str } if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_front, pph_trace_unmerged_key); + pph_trace_tree (decl, name, pph_trace_front, pph_trace_unmerged_key); name_id = pph_in_tree (stream); if (decl == read_decl) @@ -2334,7 +2332,7 @@ pph_in_merge_key_namespace_decl (pph_str } if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_back, pph_trace_unmerged_key); + pph_trace_tree (decl, name, pph_trace_back, pph_trace_unmerged_key); } @@ -2382,7 +2380,7 @@ pph_in_merge_body_namespace_decl (pph_st } if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_front, pph_trace_merge_body); + pph_trace_tree (decl, "?", pph_trace_front, pph_trace_merge_body); gcc_assert (DECL_NAME (decl)); @@ -2399,7 +2397,7 @@ pph_in_merge_body_namespace_decl (pph_st } if (flag_pph_tracer) - pph_trace_tree (decl, pph_trace_back, pph_trace_merge_body); + pph_trace_tree (decl, NULL, pph_trace_back, pph_trace_merge_body); } @@ -2427,47 +2425,37 @@ pph_in_merge_key_tree (pph_stream *strea /* Materialize a new node from STREAM. This will also read all the language-independent bitfields for the new tree. */ read_expr = pph_in_tree_header (stream, &fully_read_p); - gcc_assert (!fully_read_p && pph_tree_is_mergeable (read_expr)); - name = pph_in_string (stream); - - /* If we are merging into an existing CHAIN. Look for a match in - CHAIN to READ_EXPR's header. If we found a match, EXPR will be - the existing tree that matches READ_EXPR. Otherwise, EXPR is the - newly allocated READ_EXPR. */ - expr = (chain) ? pph_merge_into_chain (read_expr, name, chain) : read_expr; - gcc_assert (expr != NULL); + gcc_assert (!fully_read_p); - pph_cache_insert_at (&stream->cache, expr, ix, pph_tree_code_to_tag (expr)); + if (DECL_P (read_expr)) + { + gcc_assert (chain); + name = pph_in_string (stream); + /* If we are merging into an existing CHAIN. Look for a match in + CHAIN to READ_EXPR's header. If we found a match, EXPR will be + the existing tree that matches READ_EXPR. Otherwise, EXPR is the + newly allocated READ_EXPR. */ + expr = pph_merge_into_chain (read_expr, name, chain); + gcc_assert (expr != NULL); + pph_cache_insert_at (&stream->cache, expr, ix, + pph_tree_code_to_tag (expr)); - if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_front, - expr == read_expr ? pph_trace_unmerged_key - : pph_trace_merged_key); + if (flag_pph_tracer) + pph_trace_tree (expr, name, pph_trace_front, + expr == read_expr ? pph_trace_unmerged_key + : pph_trace_merged_key); - if (DECL_P (expr)) - { -#if 0 -/* FIXME pph: Disable type merging for the moment. */ - else if (TREE_CODE (expr) == TYPE_DECL) - /* Types are not on a chain. */ - TREE_TYPE (expr) = pph_in_merge_key_tree (stream, NULL); + if (flag_pph_tracer) + pph_trace_tree (expr, name, pph_trace_back, + expr == read_expr ? pph_trace_unmerged_key + : pph_trace_merged_key); } - else if (CLASS_TYPE_P (expr)) + else { - pph_in_merge_key_chain (stream, &TYPE_FIELDS (expr)); - pph_in_merge_key_chain (stream, &TYPE_METHODS (expr)); - /*FIXME pph: Nested types are broken. - pph_in_binding_table (stream, &CLASSTYPE_NESTED_UTDS (expr)); - pph_in_merge_key_chain (stream, &CLASSTYPE_DECL_LIST (expr)); - */ -#endif + gcc_assert (TYPE_P (read_expr)); + gcc_assert (false); } - if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_back, - expr == read_expr ? pph_trace_unmerged_key - : pph_trace_merged_key); - return expr; } @@ -2527,7 +2515,7 @@ pph_in_tree (pph_stream *stream) pph_cache_insert_at (&stream->cache, expr, ix, pph_tree_code_to_tag (expr)); if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_front, + pph_trace_tree (expr, "?", pph_trace_front, marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate : pph_trace_normal ); @@ -2538,7 +2526,7 @@ pph_in_tree (pph_stream *stream) pph_in_tree_body (stream, expr); if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_back, + pph_trace_tree (expr, NULL, pph_trace_back, marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate : pph_trace_normal); Index: gcc/tree-streamer-out.c =================================================================== --- gcc/tree-streamer-out.c (revision 183805) +++ gcc/tree-streamer-out.c (working copy) @@ -808,6 +808,9 @@ streamer_write_tree_body (struct output_ code = TREE_CODE (expr); + if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) + write_ts_decl_minimal_tree_pointers (ob, expr, ref_p); + if (CODE_CONTAINS_STRUCT (code, TS_TYPED)) write_ts_common_tree_pointers (ob, expr, ref_p); @@ -817,9 +820,6 @@ streamer_write_tree_body (struct output_ if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX)) write_ts_complex_tree_pointers (ob, expr, ref_p); - if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) - write_ts_decl_minimal_tree_pointers (ob, expr, ref_p); - if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) write_ts_decl_common_tree_pointers (ob, expr, ref_p); Index: gcc/tree-streamer-in.c =================================================================== --- gcc/tree-streamer-in.c (revision 183805) +++ gcc/tree-streamer-in.c (working copy) @@ -942,6 +942,9 @@ streamer_read_tree_body (struct lto_inpu code = TREE_CODE (expr); + if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) + lto_input_ts_decl_minimal_tree_pointers (ib, data_in, expr); + if (CODE_CONTAINS_STRUCT (code, TS_TYPED)) lto_input_ts_common_tree_pointers (ib, data_in, expr); @@ -951,9 +954,6 @@ streamer_read_tree_body (struct lto_inpu if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX)) lto_input_ts_complex_tree_pointers (ib, data_in, expr); - if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) - lto_input_ts_decl_minimal_tree_pointers (ib, data_in, expr); - if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) lto_input_ts_decl_common_tree_pointers (ib, data_in, expr); -- This patch is available for review at http://codereview.appspot.com/5616043