Add a new flag -fpph-untree. In pph_stream_read_tree and pph_stream_write_tree:
Refactor from nested if statements to a switch statement. Remove handling of TREE_BINFO, as it is redundant. For TEMPLATE_DECL, also stream DECL_MEMBER_TEMPLATE_P. Report unhandled trees when -fpph-untree. Remove pph_stream_read_tree_vec_none and pph_stream_write_tree_vec_none, which are unused with the removal of the handling of TREE_BINFO above. The code edits do NOT conform with the gcc style. This is deliberate so that diff reports sensible differences. I will make a separate patch to fix the style. Index: gcc/c-family/ChangeLog.pph 2011-05-24 Lawrence Crowl <cr...@google.com> * c.opt (fpph-untree): Add. Index: gcc/cp/ChangeLog.pph 2011-05-24 Lawrence Crowl <cr...@google.com> * pph-streamer-in.c (pph_stream_read_tree): Refactor from nested if statements to a switch statement. For TEMPLATE_DECL, also input DECL_MEMBER_TEMPLATE_P. Report unhandled trees when -fpph-untree. Add already completely handled trees as separate cases. (pph_stream_read_tree_vec_none): Remove. * pph-streamer-out.c (pph_stream_write_tree): Refactor from nested if statements to a switch statement. For TEMPLATE_DECL, also output DECL_MEMBER_TEMPLATE_P. Report unhandled trees when -fpph-untree. Add already completely handled trees as separate cases. (pph_stream_write_tree_vec_none): Remove. Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 174130) +++ gcc/c-family/c.opt (working copy) @@ -961,6 +961,10 @@ fpph-tracer= C++ Joined RejectNegative UInteger Var(flag_pph_tracer) -fpph-tracer Enable tracing of PPH streaming operations +fpph-untree +C++ Var(flag_pph_untree) +-fpph-untree Report unrecognized trees while streaming PPH. + fpreprocessed C ObjC C++ ObjC++ Treat the input file as already preprocessed Index: gcc/cp/pph-streamer-in.c =================================================================== --- gcc/cp/pph-streamer-in.c (revision 174130) +++ gcc/cp/pph-streamer-in.c (working copy) @@ -267,22 +267,6 @@ pph_stream_read_qual_use_vec (pph_stream } -/* Read a trees from STREAM and write into a none VEC v. */ - -static VEC(tree,none) * -pph_stream_read_tree_vec_none (pph_stream *stream, VEC(tree,none) *v) -{ - unsigned i, num; - - num = pph_input_uint (stream); - VEC_embedded_init (tree, v, num); - for (i = 0; i < num; i++) - VEC_quick_push (tree, v, pph_input_tree (stream)); - - return v; -} - - /* Forward declaration to break cyclic dependencies. */ static struct cp_binding_level *pph_stream_read_binding_level (pph_stream *); @@ -821,24 +805,45 @@ pph_stream_read_tree (struct lto_input_b { pph_stream *stream = (pph_stream *) data_in->sdata; - if (DECL_P (expr)) + switch (TREE_CODE (expr)) { + case DEBUG_EXPR_DECL: + case IMPORTED_DECL: + case LABEL_DECL: + case RESULT_DECL: DECL_INITIAL (expr) = pph_input_tree (stream); + break; - if (TREE_CODE (expr) == FUNCTION_DECL - || TREE_CODE (expr) == NAMESPACE_DECL - || TREE_CODE (expr) == PARM_DECL - || LANG_DECL_HAS_MIN (expr)) + 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_input_tree (stream); pph_stream_read_lang_specific (stream, expr); - if (TREE_CODE (expr) == FUNCTION_DECL) + break; + } + + case FUNCTION_DECL: + { + DECL_INITIAL (expr) = pph_input_tree (stream); + pph_stream_read_lang_specific (stream, expr); DECL_SAVED_TREE (expr) = pph_input_tree (stream); + break; } - if (TREE_CODE (expr) == TYPE_DECL) + case TYPE_DECL: + { + DECL_INITIAL (expr) = pph_input_tree (stream); + pph_stream_read_lang_specific (stream, expr); DECL_ORIGINAL_TYPE (expr) = pph_input_tree (stream); + break; } - else if (TREE_CODE (expr) == STATEMENT_LIST) + + case STATEMENT_LIST: { HOST_WIDE_INT i, num_trees = pph_input_uint (stream); for (i = 0; i < num_trees; i++) @@ -846,56 +851,90 @@ pph_stream_read_tree (struct lto_input_b tree stmt = pph_input_tree (stream); append_to_statement_list (stmt, &expr); } + break; } - else if (TYPE_P (expr)) + + 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_stream_read_lang_type (stream, expr); - if (TREE_CODE (expr) == RECORD_TYPE - || TREE_CODE (expr) == UNION_TYPE - || TREE_CODE (expr) == QUAL_UNION_TYPE) + break; + } + + case QUAL_UNION_TYPE: + case RECORD_TYPE: + case UNION_TYPE: + { + pph_stream_read_lang_type (stream, expr); { TYPE_BINFO (expr) = pph_input_tree (stream); } + break; } - else if (TREE_CODE (expr) == OVERLOAD) + + case OVERLOAD: { OVL_FUNCTION (expr) = pph_input_tree (stream); + break; } - else if (TREE_CODE (expr) == IDENTIFIER_NODE) + + case IDENTIFIER_NODE: { struct lang_identifier *id = LANG_IDENTIFIER_CAST (expr); id->namespace_bindings = pph_stream_read_cxx_binding (stream); id->bindings = pph_stream_read_cxx_binding (stream); id->class_template_info = pph_input_tree (stream); id->label_value = pph_input_tree (stream); + break; } - else if (TREE_CODE (expr) == BASELINK) + + case BASELINK: { BASELINK_BINFO (expr) = pph_input_tree (stream); BASELINK_FUNCTIONS (expr) = pph_input_tree (stream); BASELINK_ACCESS_BINFO (expr) = pph_input_tree (stream); + break; } - else if (TREE_CODE (expr) == TREE_BINFO) - { - BINFO_OFFSET (expr) = pph_input_tree (stream); - BINFO_VTABLE (expr) = pph_input_tree (stream); - BINFO_VIRTUALS (expr) = pph_input_tree (stream); - BINFO_VPTR_FIELD (expr) = pph_input_tree (stream); - BINFO_BASE_ACCESSES (expr) = pph_stream_read_tree_vec (stream); - BINFO_INHERITANCE_CHAIN (expr) = pph_input_tree (stream); - BINFO_SUBVTT_INDEX (expr) = pph_input_tree (stream); - BINFO_VPTR_INDEX (expr) = pph_input_tree (stream); - pph_stream_read_tree_vec_none (stream, BINFO_BASE_BINFOS (expr) ); - } - else if (TREE_CODE (expr) == TEMPLATE_DECL) + + case TEMPLATE_DECL: { + DECL_INITIAL (expr) = pph_input_tree (stream); + pph_stream_read_lang_specific (stream, expr); DECL_TEMPLATE_RESULT (expr) = pph_input_tree (stream); DECL_TEMPLATE_PARMS (expr) = pph_input_tree (stream); DECL_CONTEXT (expr) = pph_input_tree (stream); + break; } - else if (TREE_CODE (expr) == TEMPLATE_INFO) + + case TEMPLATE_INFO: { TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr) = pph_stream_read_qual_use_vec (stream); + break; + } + + case TREE_LIST: + case TREE_BINFO: + /* These trees are already fully handled. */ + break; + + default: + if (flag_pph_untree) + fprintf (pph_logfile, "PPH: unrecognized tree node %s\n", + tree_code_name[TREE_CODE (expr)]); } } Index: gcc/cp/pph-streamer-out.c =================================================================== --- gcc/cp/pph-streamer-out.c (revision 174130) +++ gcc/cp/pph-streamer-out.c (working copy) @@ -297,22 +297,6 @@ pph_stream_write_qual_use_vec (pph_strea } -/* Write all the trees in non VEC V to STREAM. REF_P is true if the - trees should be written as references. */ - -static void -pph_stream_write_tree_vec_none (pph_stream *stream, VEC(tree,none) *v, - bool ref_p) -{ - unsigned i; - tree t; - - pph_output_uint (stream, VEC_length (tree, v)); - for (i = 0; VEC_iterate (tree, v, i, t); i++) - pph_output_tree_or_ref (stream, t, ref_p); -} - - /* Forward declaration to break cyclic dependencies. */ static void pph_stream_write_binding_level (pph_stream *, struct cp_binding_level *, bool); @@ -822,25 +806,45 @@ pph_stream_write_tree (struct output_blo { pph_stream *stream = (pph_stream *) ob->sdata; - if (DECL_P (expr)) + switch (TREE_CODE (expr)) { + case DEBUG_EXPR_DECL: + case IMPORTED_DECL: + case LABEL_DECL: + case RESULT_DECL: pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3); + break; - if (TREE_CODE (expr) == FUNCTION_DECL - || TREE_CODE (expr) == NAMESPACE_DECL - || TREE_CODE (expr) == PARM_DECL - || LANG_DECL_HAS_MIN (expr)) + 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_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3); pph_stream_write_lang_specific (stream, expr, ref_p); + break; + } - if (TREE_CODE (expr) == FUNCTION_DECL) + case FUNCTION_DECL: + { + pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3); + pph_stream_write_lang_specific (stream, expr, ref_p); pph_output_tree_or_ref_1 (stream, DECL_SAVED_TREE (expr), ref_p, 3); + break; } - if (TREE_CODE (expr) == TYPE_DECL) + case TYPE_DECL: + { + pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3); + pph_stream_write_lang_specific (stream, expr, ref_p); pph_output_tree_or_ref_1 (stream, DECL_ORIGINAL_TYPE (expr), ref_p, 3); + break; } - else if (TREE_CODE (expr) == STATEMENT_LIST) + + case STATEMENT_LIST: { tree_stmt_iterator i; unsigned num_stmts; @@ -854,58 +858,92 @@ pph_stream_write_tree (struct output_blo /* Write the statements. */ for (i = tsi_start (expr); !tsi_end_p (i); tsi_next (&i)) pph_output_tree_or_ref_1 (stream, tsi_stmt (i), ref_p, 3); + break; } - else if (TYPE_P (expr)) + + 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_stream_write_lang_type (stream, expr, ref_p); - if (TREE_CODE (expr) == RECORD_TYPE - || TREE_CODE (expr) == UNION_TYPE - || TREE_CODE (expr) == QUAL_UNION_TYPE) + break; + } + + case QUAL_UNION_TYPE: + case RECORD_TYPE: + case UNION_TYPE: + { + pph_stream_write_lang_type (stream, expr, ref_p); { pph_output_tree_or_ref_1 (stream, TYPE_BINFO (expr), ref_p, 3); } + break; } - else if (TREE_CODE (expr) == OVERLOAD) + + case OVERLOAD: { pph_output_tree_or_ref_1 (stream, OVL_CURRENT (expr), ref_p, 3); + break; } - else if (TREE_CODE (expr) == IDENTIFIER_NODE) + + case IDENTIFIER_NODE: { struct lang_identifier *id = LANG_IDENTIFIER_CAST (expr); pph_stream_write_cxx_binding (stream, id->namespace_bindings, ref_p); pph_stream_write_cxx_binding (stream, id->bindings, ref_p); pph_output_tree_or_ref_1 (stream, id->class_template_info, ref_p, 3); pph_output_tree_or_ref_1 (stream, id->label_value, ref_p, 3); + break; } - else if (TREE_CODE (expr) == BASELINK) + + case BASELINK: { pph_output_tree_or_ref_1 (stream, BASELINK_BINFO (expr), ref_p, 3); pph_output_tree_or_ref_1 (stream, BASELINK_FUNCTIONS (expr), ref_p, 3); pph_output_tree_or_ref_1 (stream, BASELINK_ACCESS_BINFO (expr), ref_p, 3); + break; } - else if (TREE_CODE (expr) == TREE_BINFO) - { - pph_output_tree_or_ref_1 (stream, BINFO_OFFSET (expr), ref_p, 3); - pph_output_tree_or_ref_1 (stream, BINFO_VTABLE (expr), ref_p, 3); - pph_output_tree_or_ref_1 (stream, BINFO_VIRTUALS (expr), ref_p, 3); - pph_output_tree_or_ref_1 (stream, BINFO_VPTR_FIELD (expr), ref_p, 3); - pph_stream_write_tree_vec (stream, BINFO_BASE_ACCESSES (expr), ref_p); - pph_output_tree_or_ref_1 (stream, BINFO_INHERITANCE_CHAIN (expr), - ref_p, 3); - pph_output_tree_or_ref_1 (stream, BINFO_SUBVTT_INDEX (expr), ref_p, 3); - pph_output_tree_or_ref_1 (stream, BINFO_VPTR_INDEX (expr), ref_p, 3); - pph_stream_write_tree_vec_none (stream, BINFO_BASE_BINFOS (expr), ref_p); - } - else if (TREE_CODE (expr) == TEMPLATE_DECL) + + case TEMPLATE_DECL: { + pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3); + pph_stream_write_lang_specific (stream, expr, ref_p); pph_output_tree_or_ref_1 (stream, DECL_TEMPLATE_RESULT (expr), ref_p, 3); pph_output_tree_or_ref_1 (stream, DECL_TEMPLATE_PARMS (expr), ref_p, 3); pph_output_tree_or_ref_1 (stream, DECL_CONTEXT (expr), ref_p, 3); + pph_output_uchar (stream, DECL_MEMBER_TEMPLATE_P (expr)); + break; } - else if (TREE_CODE (expr) == TEMPLATE_INFO) + + case TEMPLATE_INFO: { pph_stream_write_qual_use_vec (stream, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr), ref_p); + break; + } + + case TREE_LIST: + case TREE_BINFO: + /* These trees are already fully handled. */ + break; + + default: + if (flag_pph_untree) + fprintf (pph_logfile, "PPH: unrecognized tree node %s\n", + tree_code_name[TREE_CODE (expr)]); } } -- This patch is available for review at http://codereview.appspot.com/4528096