- break;
-
- case VAR_DECL:
- case DEBUG_EXPR_DECL:
- gcc_assert (decl_function_context (expr) == NULL
- || TREE_STATIC (expr));
- output_record_start (ob, LTO_global_decl_ref);
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case CONST_DECL:
- output_record_start (ob, LTO_const_decl_ref);
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case IMPORTED_DECL:
- gcc_assert (decl_function_context (expr) == NULL);
- output_record_start (ob, LTO_imported_decl_ref);
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case TYPE_DECL:
- output_record_start (ob, LTO_type_decl_ref);
- lto_output_type_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case NAMESPACE_DECL:
- output_record_start (ob, LTO_namespace_decl_ref);
- lto_output_namespace_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case LABEL_DECL:
- output_record_start (ob, LTO_label_decl_ref);
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case RESULT_DECL:
- output_record_start (ob, LTO_result_decl_ref);
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- case TRANSLATION_UNIT_DECL:
- output_record_start (ob, LTO_translation_unit_decl_ref);
- lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
- break;
-
- default:
- /* No other node is indexable, so it should have been handled
- by lto_output_tree. */
- gcc_unreachable ();
- }
-}
-
-
-/* If REF_P is true, emit a reference to EXPR in output block OB,
- otherwise emit the physical representation of EXPR in OB. */
-
-static inline void
-lto_output_tree_or_ref (struct output_block *ob, tree expr, bool ref_p)
-{
- if (ref_p)
- lto_output_tree_ref (ob, expr);
- else
- lto_output_tree (ob, expr, false);
-}
-
-
-/* Emit the chain of tree nodes starting at T. OB is the output block
- to write to. REF_P is true if chain elements should be emitted
- as references. */
-
-static void
-lto_output_chain (struct output_block *ob, tree t, bool ref_p)
-{
- int i, count;
-
- count = list_length (t);
- output_sleb128 (ob, count);
- for (i = 0; i < count; i++)
- {
- tree saved_chain;
-
- /* Clear TREE_CHAIN to avoid blindly recursing into the rest
- of the list. */
- saved_chain = TREE_CHAIN (t);
- TREE_CHAIN (t) = NULL_TREE;
-
- lto_output_tree_or_ref (ob, t, ref_p);
-
- TREE_CHAIN (t) = saved_chain;
- t = TREE_CHAIN (t);
- }
-}
-
-
-/* Write all pointer fields in the TS_COMMON structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_common_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- if (TREE_CODE (expr) != IDENTIFIER_NODE)
- lto_output_tree_or_ref (ob, TREE_TYPE (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_VECTOR structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_vector_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- lto_output_chain (ob, TREE_VECTOR_CST_ELTS (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_COMPLEX structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_complex_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- lto_output_tree_or_ref (ob, TREE_REALPART (expr), ref_p);
- lto_output_tree_or_ref (ob, TREE_IMAGPART (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_DECL_MINIMAL structure of EXPR
- to output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- lto_output_tree_or_ref (ob, DECL_NAME (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_CONTEXT (expr), ref_p);
- lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
-}
-
-
-/* Write all pointer fields in the TS_DECL_COMMON structure of EXPR to
- output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- lto_output_tree_or_ref (ob, DECL_SIZE (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_SIZE_UNIT (expr), ref_p);
-
- if (TREE_CODE (expr) != FUNCTION_DECL
- && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
- {
- tree initial = DECL_INITIAL (expr);
- if (TREE_CODE (expr) == VAR_DECL
- && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
- && initial)
- {
- lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
- struct varpool_node *vnode = varpool_get_node (expr);
- if (!vnode)
- initial = error_mark_node;
- else if (!lto_varpool_encoder_encode_initializer_p (varpool_encoder,
- vnode))
- initial = NULL;
- }
-
- lto_output_tree_or_ref (ob, initial, ref_p);
- }
-
- lto_output_tree_or_ref (ob, DECL_ATTRIBUTES (expr), ref_p);
- /* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
-
- if (TREE_CODE (expr) == PARM_DECL)
- lto_output_chain (ob, TREE_CHAIN (expr), ref_p);
-
- if ((TREE_CODE (expr) == VAR_DECL
- || TREE_CODE (expr) == PARM_DECL)
- && DECL_HAS_VALUE_EXPR_P (expr))
- lto_output_tree_or_ref (ob, DECL_VALUE_EXPR (expr), ref_p);
-
- if (TREE_CODE (expr) == VAR_DECL)
- lto_output_tree_or_ref (ob, DECL_DEBUG_EXPR (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_DECL_NON_COMMON structure of
- EXPR to output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_decl_non_common_tree_pointers (struct output_block *ob,
- tree expr, bool ref_p)
-{
- if (TREE_CODE (expr) == FUNCTION_DECL)
- {
- /* DECL_SAVED_TREE holds the GENERIC representation for DECL.
- At this point, it should not exist. Either because it was
- converted to gimple or because DECL didn't have a GENERIC
- representation in this TU. */
- gcc_assert (DECL_SAVED_TREE (expr) == NULL_TREE);
- lto_output_tree_or_ref (ob, DECL_ARGUMENTS (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_RESULT (expr), ref_p);
- }
- lto_output_tree_or_ref (ob, DECL_VINDEX (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_DECL_WITH_VIS structure of EXPR
- to output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- /* Make sure we don't inadvertently set the assembler name. */
- if (DECL_ASSEMBLER_NAME_SET_P (expr))
- lto_output_tree_or_ref (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
- else
- output_zero (ob);
-
- lto_output_tree_or_ref (ob, DECL_SECTION_NAME (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_COMDAT_GROUP (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_FIELD_DECL structure of EXPR to
- output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- lto_output_tree_or_ref (ob, DECL_FIELD_OFFSET (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_QUALIFIER (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_FCONTEXT (expr), ref_p);
- lto_output_chain (ob, TREE_CHAIN (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_FUNCTION_DECL structure of EXPR
- to output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- /* DECL_STRUCT_FUNCTION is handled by lto_output_function. FIXME lto,
- maybe it should be handled here? */
- lto_output_tree_or_ref (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
- lto_output_tree_or_ref (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr),
- ref_p);
-}
-
-
-/* Write all pointer fields in the TS_TYPE structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_type_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- if (TREE_CODE (expr) == ENUMERAL_TYPE)
- lto_output_tree_or_ref (ob, TYPE_VALUES (expr), ref_p);
- else if (TREE_CODE (expr) == ARRAY_TYPE)
- lto_output_tree_or_ref (ob, TYPE_DOMAIN (expr), ref_p);
- else if (RECORD_OR_UNION_TYPE_P (expr))
- lto_output_tree_or_ref (ob, TYPE_FIELDS (expr), ref_p);
- else if (TREE_CODE (expr) == FUNCTION_TYPE
- || TREE_CODE (expr) == METHOD_TYPE)
- lto_output_tree_or_ref (ob, TYPE_ARG_TYPES (expr), ref_p);
-
- lto_output_tree_or_ref (ob, TYPE_SIZE (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_SIZE_UNIT (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_ATTRIBUTES (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
- /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO nor
- TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO. */
- if (!POINTER_TYPE_P (expr))
- lto_output_tree_or_ref (ob, TYPE_MINVAL (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_MAXVAL (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p);
- /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
- during fixup. */
- if (RECORD_OR_UNION_TYPE_P (expr))
- lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
- lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
- /* TYPE_CANONICAL is re-computed during type merging, so no need
- to stream it here. */
- lto_output_tree_or_ref (ob, TYPE_STUB_DECL (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_LIST structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_list_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- lto_output_tree_or_ref (ob, TREE_PURPOSE (expr), ref_p);
- lto_output_tree_or_ref (ob, TREE_VALUE (expr), ref_p);
- lto_output_chain (ob, TREE_CHAIN (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_VEC structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_vec_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
-{
- int i;
-
- /* Note that the number of slots for EXPR has already been emitted
- in EXPR's header (see lto_output_tree_header). */
- for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
- lto_output_tree_or_ref (ob, TREE_VEC_ELT (expr, i), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_EXP structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
-{
- int i;
-
- output_sleb128 (ob, TREE_OPERAND_LENGTH (expr));
- for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
- lto_output_tree_or_ref (ob, TREE_OPERAND (expr, i), ref_p);
- lto_output_location (ob, EXPR_LOCATION (expr));
- lto_output_tree_or_ref (ob, TREE_BLOCK (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_BLOCK structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_block_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- /* Do not stream BLOCK_SOURCE_LOCATION. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
- lto_output_chain (ob, BLOCK_VARS (expr), ref_p);
-
- /* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
-
- lto_output_tree_or_ref (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
- /* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
- lto_output_tree_or_ref (ob, BLOCK_FRAGMENT_ORIGIN (expr), ref_p);
- lto_output_tree_or_ref (ob, BLOCK_FRAGMENT_CHAIN (expr), ref_p);
- /* Do not output BLOCK_SUBBLOCKS. Instead on streaming-in this
- list is re-constructed from BLOCK_SUPERCONTEXT. */
-}
-
-
-/* Write all pointer fields in the TS_BINFO structure of EXPR to output
- block OB. If REF_P is true, write a reference to EXPR's pointer
- fields. */
-
-static void
-lto_output_ts_binfo_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- unsigned i;
- tree t;
-
- /* Note that the number of BINFO slots has already been emitted in
- EXPR's header (see lto_output_tree_header) because this length
- is needed to build the empty BINFO node on the reader side. */
- FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (expr), i, t)
- lto_output_tree_or_ref (ob, t, ref_p);
- output_zero (ob);
-
- lto_output_tree_or_ref (ob, BINFO_OFFSET (expr), ref_p);
- lto_output_tree_or_ref (ob, BINFO_VTABLE (expr), ref_p);
- lto_output_tree_or_ref (ob, BINFO_VIRTUALS (expr), ref_p);
- lto_output_tree_or_ref (ob, BINFO_VPTR_FIELD (expr), ref_p);
-
- output_uleb128 (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
- FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t)
- lto_output_tree_or_ref (ob, t, ref_p);
-
- lto_output_tree_or_ref (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
- lto_output_tree_or_ref (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
- lto_output_tree_or_ref (ob, BINFO_VPTR_INDEX (expr), ref_p);
-}
-
-
-/* Write all pointer fields in the TS_CONSTRUCTOR structure of EXPR to
- output block OB. If REF_P is true, write a reference to EXPR's
- pointer fields. */
-
-static void
-lto_output_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
- bool ref_p)
-{
- unsigned i;
- tree index, value;
-
- output_uleb128 (ob, CONSTRUCTOR_NELTS (expr));
- FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
- {
- lto_output_tree_or_ref (ob, index, ref_p);
- lto_output_tree_or_ref (ob, value, ref_p);
- }
-}
-
-/* Write a TS_TARGET_OPTION tree in EXPR to OB. */
-
-static void
-lto_output_ts_target_option (struct output_block *ob, tree expr)
-{
- struct cl_target_option *t = TREE_TARGET_OPTION (expr);
- struct bitpack_d bp;
- unsigned i, len;
-
- /* The cl_target_option is target specific and generated by the options
- awk script, so we just recreate a byte-by-byte copy here. */
-
- bp = bitpack_create (ob->main_stream);
- len = sizeof (struct cl_target_option);
- for (i = 0; i < len; i++)
- bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
- /* Catch struct size mismatches between reader and writer. */
- bp_pack_value (&bp, 0x12345678, 32);
- lto_output_bitpack (&bp);
-}
-
-/* Write a TS_TRANSLATION_UNIT_DECL tree in EXPR to OB. */
-
-static void
-lto_output_ts_translation_unit_decl_tree_pointers (struct output_block *ob,
- tree expr)
-{
- output_string (ob, ob->main_stream, TRANSLATION_UNIT_LANGUAGE (expr));
-}
-
-/* Helper for lto_output_tree. Write all pointer fields in EXPR to output
- block OB. If REF_P is true, the leaves of EXPR are emitted as
- references. */
-
-static void
-lto_output_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
-{
- enum tree_code code;
-
- code = TREE_CODE (expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
- lto_output_ts_common_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
- lto_output_ts_vector_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
- lto_output_ts_complex_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
- lto_output_ts_decl_minimal_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
- lto_output_ts_decl_common_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
- lto_output_ts_decl_non_common_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
- lto_output_ts_decl_with_vis_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
- lto_output_ts_field_decl_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
- lto_output_ts_function_decl_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TYPE))
- lto_output_ts_type_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_LIST))
- lto_output_ts_list_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_VEC))
- lto_output_ts_vec_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_EXP))
- lto_output_ts_exp_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_SSA_NAME))
- {
- /* We only stream the version number of SSA names. */
- gcc_unreachable ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
- lto_output_ts_block_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
- lto_output_ts_binfo_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
- lto_output_ts_constructor_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_STATEMENT_LIST))
- {
- /* This should only appear in GENERIC. */
- gcc_unreachable ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_OMP_CLAUSE))
- {
- /* This should only appear in High GIMPLE. */
- gcc_unreachable ();
- }