We were not streaming the TS_COMMON field change. This patch adds a functions to stream TS_COMMON. It adds calls to them in existing code that handles trees. It also implements streaming of other C++-specific trees that inherit TS_COMMON. This patch fixes some ICEs, but the test still fail on later ICEs. Tests adjusted to reflect new reality. Tested on x86-64. Committed. Index: gcc/testsuite/ChangeLog.pph 2011-06-05 Lawrence Crowl <crowl@google.com> * g++.dg/pph/x1special.cc: Change to new ICE. * g++.dg/pph/x1template.cc: Change old ICE to new location. * g++.dg/pph/x1tmplfunc.cc: Change to new ICE. Index: gcc/cp/ChangeLog.pph 2011-06-05 Lawrence Crowl <crowl@google.com> * pph-streamer.c (pph_trace): Clean up trace formatting. * pph-streamer-in.c (pph_in_tree_common): New for TS_COMMON chain. (pph_read_tree): Call pph_in_tree_common in existing readers for trees. Implement readers for C++-specific trees that need pph_in_tree_common. * pph-streamer-out.c (pph_out_tree_common): New for TS_COMMON chain. (pph_write_tree): Call pph_out_tree_common in existing writers for trees. Implement readers for C++-specific trees that need pph_out_tree_common. Index: gcc/testsuite/g++.dg/pph/x1tmplfunc.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x1tmplfunc.cc (revision 174669) +++ gcc/testsuite/g++.dg/pph/x1tmplfunc.cc (working copy) @@ -1,5 +1,5 @@ // { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } } -// { dg-bogus "x1tmplfunc.h:12:30: internal compiler error: Segmentation fault" "" { xfail *-*-* } 0 } +// { dg-bogus "x1tmplfunc.h:8:16: internal compiler error: Segmentation fault" "" { xfail *-*-* } 0 } // { dg-prune-output "In file included from " } #include "x1tmplfunc.h" Index: gcc/testsuite/g++.dg/pph/x1special.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x1special.cc (revision 174669) +++ gcc/testsuite/g++.dg/pph/x1special.cc (working copy) @@ -1,5 +1,5 @@ // { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } } -// { dg-bogus "x1special.h:19:6: internal compiler error: tree check: expected tree that contains 'decl minimal' structure, have 'overload' in context_for_name_lookup, at cp/search.c:570" "" { xfail *-*-* } 0 } +// { dg-bogus "x1special.h:10:5: internal compiler error: Segmentation fault" "" { xfail *-*-* } 0 } // { dg-prune-output "In file included from " } #include "x1special.h" Index: gcc/testsuite/g++.dg/pph/x1template.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x1template.cc (revision 174669) +++ gcc/testsuite/g++.dg/pph/x1template.cc (working copy) @@ -1,5 +1,5 @@ // { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } } -// { dg-bogus "x1template.h:18:13: internal compiler error: in resume_scope, at cp/name-lookup.c:1573" "" { xfail *-*-* } 0 } +// { dg-bogus "x1template.h:18:13: internal compiler error: in resume_scope, at cp/name-lookup.c:1567" "" { xfail *-*-* } 0 } // { dg-prune-output "In file included from " } #include "x1template.h" Index: gcc/cp/pph-streamer-in.c =================================================================== --- gcc/cp/pph-streamer-in.c (revision 174669) +++ gcc/cp/pph-streamer-in.c (working copy) @@ -484,6 +484,15 @@ pph_in_binding_level (pph_stream *stream } +/* Read in the tree_common fields. */ + +static void +pph_in_tree_common (pph_stream *stream, tree t) +{ + /* The 'struct tree_typed typed' base class is handled in LTO. */ + TREE_CHAIN (t) = pph_in_tree (stream); +} + /* Read and return an instance of struct c_language_function from STREAM. */ static struct c_language_function * @@ -1007,6 +1016,7 @@ pph_read_tree (struct lto_input_block *i /* tcc_exceptional */ case OVERLOAD: + pph_in_tree_common (stream, expr); OVL_FUNCTION (expr) = pph_in_tree (stream); break; @@ -1021,12 +1031,14 @@ pph_read_tree (struct lto_input_block *i break; case BASELINK: + pph_in_tree_common (stream, expr); BASELINK_BINFO (expr) = pph_in_tree (stream); BASELINK_FUNCTIONS (expr) = pph_in_tree (stream); BASELINK_ACCESS_BINFO (expr) = pph_in_tree (stream); break; case TEMPLATE_INFO: + pph_in_tree_common (stream, expr); TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr) = pph_in_qual_use_vec (stream); break; @@ -1034,6 +1046,7 @@ pph_read_tree (struct lto_input_block *i 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); @@ -1044,6 +1057,56 @@ pph_read_tree (struct lto_input_block *i } 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) = pth_load_token_cache (stream); + DEFARG_INSTANTIATIONS (expr) = pph_in_tree_vec (stream); + break; + + case STATIC_ASSERT: + pph_in_tree_common (stream, expr); + STATIC_ASSERT_CONDITION (expr) = pph_in_tree (stream); + STATIC_ASSERT_MESSAGE (expr) = pph_in_tree (stream); + /* FIXME pph: also STATIC_ASSERT_SOURCE_LOCATION (expr). */ + break; + + case ARGUMENT_PACK_SELECT: + pph_in_tree_common (stream, expr); + ARGUMENT_PACK_SELECT_FROM_PACK (expr) = pph_in_tree (stream); + ARGUMENT_PACK_SELECT_INDEX (expr) = pph_in_uint (stream); + break; + + case TRAIT_EXPR: + pph_in_tree_common (stream, expr); + TRAIT_EXPR_TYPE1 (expr) = pph_in_tree (stream); + TRAIT_EXPR_TYPE2 (expr) = pph_in_tree (stream); + TRAIT_EXPR_KIND (expr) = (enum cp_trait_kind) pph_in_uint (stream); + break; + + case LAMBDA_EXPR: + { + struct tree_lambda_expr *e + = (struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (expr); + pph_in_tree_common (stream, expr); + /* FIXME pph: also e->locus. */ + e->capture_list = pph_in_tree (stream); + e->this_capture = pph_in_tree (stream); + e->return_type = pph_in_tree (stream); + e->extra_scope = pph_in_tree (stream); + e->discriminator = pph_in_uint (stream); + } + break; + + /* TREES ALREADY HANDLED */ /* tcc_declaration */ @@ -1058,6 +1121,7 @@ pph_read_tree (struct lto_input_block *i break; + /* TREES UNIMPLEMENTED */ /* tcc_declaration */ @@ -1129,27 +1193,17 @@ pph_read_tree (struct lto_input_block *i case OFFSET_REF: case SCOPE_REF: - /* tcc_constant */ - - case PTRMEM_CST: - /* tcc_vl_exp */ case AGGR_INIT_EXPR: - /* tcc_exceptional */ - - case DEFAULT_ARG: - case STATIC_ASSERT: - case ARGUMENT_PACK_SELECT: - case TRAIT_EXPR: - case LAMBDA_EXPR: if (flag_pph_untree) fprintf (pph_logfile, "PPH: unimplemented tree node %s\n", tree_code_name[TREE_CODE (expr)]); break; + /* TREES UNRECOGNIZED */ default: Index: gcc/cp/pph-streamer.c =================================================================== --- gcc/cp/pph-streamer.c (revision 174669) +++ gcc/cp/pph-streamer.c (working copy) @@ -177,43 +177,35 @@ pph_trace (pph_stream *stream, const voi && flag_pph_tracer <= 3) return; - fprintf (pph_logfile, "*** %s: %s%s/%u, value=", + fprintf (pph_logfile, "PPH: %s %s %s/%u", stream->name, op, type_s[type], (unsigned) nbytes); switch (type) { case PPH_TRACE_TREE: - { - const_tree t = (const_tree) data; - if (t) - { - print_generic_expr (pph_logfile, CONST_CAST (union tree_node *, t), - 0); - fprintf (pph_logfile, ", code=%s", tree_code_name[TREE_CODE (t)]); - } - else - fprintf (pph_logfile, "NULL_TREE"); - } - break; - case PPH_TRACE_REF: { const_tree t = (const_tree) data; if (t) - { - print_generic_expr (pph_logfile, CONST_CAST (union tree_node *, t), - 0); - fprintf (pph_logfile, ", code=%s", tree_code_name[TREE_CODE (t)]); - } + { + fprintf (pph_logfile, ", code=%s", tree_code_name[TREE_CODE (t)]); + if (DECL_P (t)) + { + const char *label = type == PPH_TRACE_TREE ? "value" : "refer"; + fprintf (pph_logfile, ", %s=", label ); + print_generic_decl (pph_logfile, + CONST_CAST (union tree_node *, t), 0); + } + } else - fprintf (pph_logfile, "NULL_TREE"); + fprintf (pph_logfile, ", NULL_TREE"); } break; case PPH_TRACE_UINT: { unsigned int val = *((const unsigned int *) data); - fprintf (pph_logfile, "%u (0x%x)", val, val); + fprintf (pph_logfile, ", value=%u (0x%x)", val, val); } break; @@ -221,6 +213,7 @@ pph_trace (pph_stream *stream, const voi { size_t i; const char *buffer = (const char *) data; + fprintf (pph_logfile, ", value="); for (i = 0; i < MIN (nbytes, 100); i++) { if (ISPRINT (buffer[i])) @@ -233,14 +226,16 @@ pph_trace (pph_stream *stream, const voi case PPH_TRACE_STRING: if (data) - fprintf (pph_logfile, "%.*s", (int) nbytes, (const char *) data); + fprintf (pph_logfile, ", value=%.*s", + (int) nbytes, (const char *) data); else - fprintf (pph_logfile, "<nil>"); + fprintf (pph_logfile, ", NULL_STRING"); break; case PPH_TRACE_CHAIN: { const_tree t = (const_tree) data; + fprintf (pph_logfile, ", value=" ); print_generic_expr (pph_logfile, CONST_CAST (union tree_node *, t), TDF_SLIM); fprintf (pph_logfile, " (%d nodes in chain)", list_length (t)); @@ -250,7 +245,7 @@ pph_trace (pph_stream *stream, const voi case PPH_TRACE_BITPACK: { const struct bitpack_d *bp = (const struct bitpack_d *) data; - fprintf (pph_logfile, "0x%lx", bp->word); + fprintf (pph_logfile, ", value=0x%lx", bp->word); } break; Index: gcc/cp/pph-streamer-out.c =================================================================== --- gcc/cp/pph-streamer-out.c (revision 174669) +++ gcc/cp/pph-streamer-out.c (working copy) @@ -302,7 +302,7 @@ pph_out_qual_use_vec (pph_stream *stream { pph_out_tree_or_ref (stream, q->typedef_decl, ref_p); pph_out_tree_or_ref (stream, q->context, ref_p); - /* FIXME pph: also write location? */ + /* FIXME pph: also write location. */ } } @@ -486,6 +486,16 @@ pph_out_binding_level (pph_stream *strea } +/* Write out the tree_common fields. */ + +static void +pph_out_tree_common (pph_stream *stream, tree t, bool ref_p) +{ + /* The 'struct tree_typed typed' base class is handled in LTO. */ + pph_out_tree_or_ref (stream, TREE_CHAIN (t), ref_p); +} + + /* Write all the fields of c_language_function instance CLF to STREAM. If REF_P is true, all tree fields should be written as references. */ @@ -962,6 +972,7 @@ pph_write_tree (struct output_block *ob, /* tcc_exceptional */ case OVERLOAD: + pph_out_tree_common (stream, expr, ref_p); pph_out_tree_or_ref_1 (stream, OVL_CURRENT (expr), ref_p, 3); break; @@ -976,12 +987,14 @@ pph_write_tree (struct output_block *ob, break; case BASELINK: + pph_out_tree_common (stream, expr, ref_p); pph_out_tree_or_ref_1 (stream, BASELINK_BINFO (expr), ref_p, 3); pph_out_tree_or_ref_1 (stream, BASELINK_FUNCTIONS (expr), ref_p, 3); pph_out_tree_or_ref_1 (stream, BASELINK_ACCESS_BINFO (expr), ref_p, 3); break; case TEMPLATE_INFO: + pph_out_tree_common (stream, expr, ref_p); pph_out_qual_use_vec (stream, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr), ref_p); break; @@ -989,6 +1002,7 @@ pph_write_tree (struct output_block *ob, case TEMPLATE_PARM_INDEX: { template_parm_index *p = TEMPLATE_PARM_INDEX_CAST (expr); + pph_out_tree_common (stream, expr, ref_p); pph_out_uint (stream, p->index); pph_out_uint (stream, p->level); pph_out_uint (stream, p->orig_level); @@ -999,6 +1013,57 @@ pph_write_tree (struct output_block *ob, } break; + /* tcc_constant */ + + case PTRMEM_CST: + pph_out_tree_common (stream, expr, ref_p); + pph_out_tree_or_ref_1 (stream, PTRMEM_CST_MEMBER (expr), ref_p, 3); + break; + + /* tcc_exceptional */ + + case DEFAULT_ARG: + pph_out_tree_common (stream, expr, ref_p); + pth_save_token_cache (DEFARG_TOKENS (expr), stream); + pph_out_tree_vec (stream, DEFARG_INSTANTIATIONS (expr), ref_p); + break; + + case STATIC_ASSERT: + pph_out_tree_common (stream, expr, ref_p); + pph_out_tree_or_ref_1 (stream, STATIC_ASSERT_CONDITION (expr), ref_p, 3); + pph_out_tree_or_ref_1 (stream, STATIC_ASSERT_MESSAGE (expr), ref_p, 3); + /* FIXME pph: also STATIC_ASSERT_SOURCE_LOCATION (expr). */ + break; + + case ARGUMENT_PACK_SELECT: + pph_out_tree_common (stream, expr, ref_p); + pph_out_tree_or_ref_1 (stream, ARGUMENT_PACK_SELECT_FROM_PACK (expr), + ref_p, 3); + pph_out_uint (stream, ARGUMENT_PACK_SELECT_INDEX (expr)); + break; + + case TRAIT_EXPR: + pph_out_tree_common (stream, expr, ref_p); + pph_out_tree_or_ref_1 (stream, TRAIT_EXPR_TYPE1 (expr), ref_p, 3); + pph_out_tree_or_ref_1 (stream, TRAIT_EXPR_TYPE2 (expr), ref_p, 3); + pph_out_uint (stream, TRAIT_EXPR_KIND (expr)); + break; + + case LAMBDA_EXPR: + { + struct tree_lambda_expr *e + = (struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (expr); + pph_out_tree_common (stream, expr, ref_p); + /* FIXME pph: also e->locus. */ + pph_out_tree_or_ref_1 (stream, e->capture_list, ref_p, 3); + pph_out_tree_or_ref_1 (stream, e->this_capture, ref_p, 3); + pph_out_tree_or_ref_1 (stream, e->return_type, ref_p, 3); + pph_out_tree_or_ref_1 (stream, e->extra_scope, ref_p, 3); + pph_out_uint (stream, e->discriminator); + } + break; + + /* TREES ALREADY HANDLED */ /* tcc_declaration */ @@ -1084,27 +1149,17 @@ pph_write_tree (struct output_block *ob, case OFFSET_REF: case SCOPE_REF: - /* tcc_constant */ - - case PTRMEM_CST: - /* tcc_vl_exp */ case AGGR_INIT_EXPR: - /* tcc_exceptional */ - - case DEFAULT_ARG: - case STATIC_ASSERT: - case ARGUMENT_PACK_SELECT: - case TRAIT_EXPR: - case LAMBDA_EXPR: if (flag_pph_untree) fprintf (pph_logfile, "PPH: unimplemented tree node %s\n", tree_code_name[TREE_CODE (expr)]); break; + /* TREES UNRECOGNIZED */ default: -- This patch is available for review at http://codereview.appspot.com/4564058