@@ -933,10 +933,6 @@ fpph-decls=
C++ Joined RejectNegative UInteger Var(flag_pph_decls)
-fpph-decls=N Enable declaration identifier output at level N from PPH support
-fpph-fmt=
-C++ Joined RejectNegative UInteger Var(flag_pph_fmt)
--fpph-fmt=N Output format is (0) normal (1) pretty summary (2) dump
-
fpph-hdr=
C++ ObjC++ Joined MissingArgError(missing filename after %qs)
-fpph-hdr=<base-name> A mapping from <base-name>.h to <base-name>.pph
@@ -1012,11 +1012,11 @@ struct GTY(()) language_function {
tree x_vtt_parm;
tree x_return_value;
- BOOL_BITFIELD returns_value : 1;
- BOOL_BITFIELD returns_null : 1;
- BOOL_BITFIELD returns_abnormally : 1;
- BOOL_BITFIELD in_function_try_handler : 1;
- BOOL_BITFIELD in_base_initializer : 1;
+ BOOL_BITFIELD x_returns_value : 1;
+ BOOL_BITFIELD x_returns_null : 1;
+ BOOL_BITFIELD x_returns_abnormally : 1;
+ BOOL_BITFIELD x_in_function_try_handler : 1;
+ BOOL_BITFIELD x_in_base_initializer : 1;
/* True if this function can throw an exception. */
BOOL_BITFIELD can_throw : 1;
@@ -1067,23 +1067,23 @@ struct GTY(()) language_function {
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
-#define current_function_returns_value cp_function_chain->returns_value
+#define current_function_returns_value cp_function_chain->x_returns_value
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement with no argument is seen. */
-#define current_function_returns_null cp_function_chain->returns_null
+#define current_function_returns_null cp_function_chain->x_returns_null
/* Set to 0 at beginning of a function definition, set to 1 if
a call to a noreturn function is seen. */
#define current_function_returns_abnormally \
- cp_function_chain->returns_abnormally
+ cp_function_chain->x_returns_abnormally
/* Nonzero if we are processing a base initializer. Zero elsewhere. */
-#define in_base_initializer cp_function_chain->in_base_initializer
+#define in_base_initializer cp_function_chain->x_in_base_initializer
-#define in_function_try_handler cp_function_chain->in_function_try_handler
+#define in_function_try_handler cp_function_chain->x_in_function_try_handler
/* Expression always returned from function, or error_mark_node
otherwise, for use by the automatic named return value optimization. */
@@ -135,6 +135,421 @@ pph_stream_init_write (pph_stream *stream)
lto_push_out_decl_state (stream->out_state);
stream->decl_state_stream = XCNEW (struct lto_output_stream);
stream->ob = create_output_block (LTO_section_decls);
+ pph_set_ob_stream (stream->ob, stream);
+}
+
+
+/* Write all the fields in lang_decl_base instance LDB to OB. */
+
+static void
+pph_stream_write_ld_base (struct output_block *ob, struct lang_decl_base *ldb)
+{
+ struct bitpack_d bp;
+
+ if (ldb == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, ldb->selector, 16);
+ bp_pack_value (&bp, ldb->language, 4);
+ bp_pack_value (&bp, ldb->use_template, 2);
+ bp_pack_value (&bp, ldb->not_really_extern, 1);
+ bp_pack_value (&bp, ldb->initialized_in_class, 1);
+ bp_pack_value (&bp, ldb->repo_available_p, 1);
+ bp_pack_value (&bp, ldb->threadprivate_or_deleted_p, 1);
+ bp_pack_value (&bp, ldb->anticipated_p, 1);
+ bp_pack_value (&bp, ldb->friend_attr, 1);
+ bp_pack_value (&bp, ldb->template_conv_p, 1);
+ bp_pack_value (&bp, ldb->odr_used, 1);
+ bp_pack_value (&bp, ldb->u2sel, 1);
+ lto_output_bitpack (&bp);
+}
+
+
+/* Write all the fields in lang_decl_min instance LDM to OB. If REF_P
+ is true, all tree fields should be written as references. */
+
+static void
+pph_stream_write_ld_min (struct output_block *ob, struct lang_decl_min *ldm,
+ bool ref_p)
+{
+ if (ldm == 0)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ gcc_assert (ldm->base.selector == 0);
+
+ lto_output_tree_or_ref (ob, ldm->template_info, ref_p);
+ if (ldm->base.u2sel == 0)
+ lto_output_tree_or_ref (ob, ldm->u2.access, ref_p);
+ else if (ldm->base.u2sel == 1)
+ lto_output_sleb128_stream (ob->main_stream, ldm->u2.discriminator);
+ else
+ gcc_unreachable ();
+}
+
+
+/* Write all the trees in VEC V to OB. REF_P is true if the trees should
+ be written as references. */
+
+static void
+pph_stream_write_tree_vec (struct output_block *ob, VEC(tree,gc) *v, bool ref_p)
+{
+ unsigned i;
+ tree t;
+
+ lto_output_uleb128_stream (ob->main_stream, VEC_length (tree, v));
+ for (i = 0; VEC_iterate (tree, v, i, t); i++)
+ lto_output_tree_or_ref (ob, t, ref_p);
+}
+
+/* Forward declaration to break cyclic dependencies. */
+static void pph_stream_write_binding_level (struct output_block *,
+ struct cp_binding_level *, bool);
+
+
+/* Helper for pph_stream_write_cxx_binding. OB, CB and REF_P are as in
+ pph_stream_write_cxx_binding. */
+
+static void
+pph_stream_write_cxx_binding_1 (struct output_block *ob, cxx_binding *cb,
+ bool ref_p)
+{
+ struct bitpack_d bp;
+
+ if (cb == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ lto_output_tree_or_ref (ob, cb->value, ref_p);
+ lto_output_tree_or_ref (ob, cb->type, ref_p);
+ pph_stream_write_binding_level (ob, cb->scope, ref_p);
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, cb->value_is_inherited, 1);
+ bp_pack_value (&bp, cb->is_local, 1);
+ lto_output_bitpack (&bp);
+}
+
+
+/* Write all the fields of cxx_binding instance CB to OB. REF_P is
+ true if the tree fields should be written as references. */
+
+static void
+pph_stream_write_cxx_binding (struct output_block *ob, cxx_binding *cb,
+ bool ref_p)
+{
+ unsigned num_bindings;
+ cxx_binding *prev;
+
+ if (cb == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ for (num_bindings = 0, prev = cb->previous; prev; prev = prev->previous)
+ num_bindings++;
+
+ /* Write the list of previous bindings. */
+ lto_output_sleb128_stream (ob->main_stream, num_bindings);
+ for (prev = cb->previous; prev; prev = prev->previous)
+ pph_stream_write_cxx_binding_1 (ob, prev, ref_p);
+
+ /* Write the current binding at the end. */
+ pph_stream_write_cxx_binding_1 (ob, cb, ref_p);
+}
+
+
+/* Write all the fields of cp_class_binding instance CB to OB. REF_P
+ is true if the tree fields should be written as references. */
+
+static void
+pph_stream_write_class_binding (struct output_block *ob,
+ cp_class_binding *cb, bool ref_p)
+{
+ if (cb == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ pph_stream_write_cxx_binding (ob, &cb->base, ref_p);
+ lto_output_tree_or_ref (ob, cb->identifier, ref_p);
+}
+
+
+/* Write all the fields of cp_label_binding instance LB to OB. If
+ REF_P is true, tree fields will be written as references. */
+
+static void
+pph_stream_write_label_binding (struct output_block *ob,
+ cp_label_binding *lb, bool ref_p)
+{
+ if (lb == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ lto_output_tree_or_ref (ob, lb->label, ref_p);
+ lto_output_tree_or_ref (ob, lb->prev_value, ref_p);
+}
+
+
+/* Write all the fields of cp_binding_level instance BL to OB. If
+ REF_P is true, tree fields will be written as references. */
+
+static void
+pph_stream_write_binding_level (struct output_block *ob,
+ struct cp_binding_level *bl, bool ref_p)
+{
+ unsigned i;
+ cp_class_binding *cs;
+ cp_label_binding *sl;
+ struct bitpack_d bp;
+
+ if (bl == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ lto_output_chain (ob, bl->names, ref_p);
+ lto_output_uleb128_stream (ob->main_stream, bl->names_size);
+ lto_output_chain (ob, bl->namespaces, ref_p);
+
+ pph_stream_write_tree_vec (ob, bl->static_decls, ref_p);
+
+ lto_output_chain (ob, bl->usings, ref_p);
+ lto_output_chain (ob, bl->using_directives, ref_p);
+
+ lto_output_uleb128_stream (ob->main_stream, VEC_length (cp_class_binding,
+ bl->class_shadowed));
+ for (i = 0; VEC_iterate (cp_class_binding, bl->class_shadowed, i, cs); i++)
+ pph_stream_write_class_binding (ob, cs, ref_p);
+
+ lto_output_tree_or_ref (ob, bl->type_shadowed, ref_p);
+
+ lto_output_uleb128_stream (ob->main_stream, VEC_length (cp_label_binding,
+ bl->shadowed_labels));
+ for (i = 0; VEC_iterate (cp_label_binding, bl->shadowed_labels, i, sl); i++)
+ pph_stream_write_label_binding (ob, sl, ref_p);
+
+ lto_output_chain (ob, bl->blocks, ref_p);
+ lto_output_tree_or_ref (ob, bl->this_entity, ref_p);
+ pph_stream_write_binding_level (ob, bl->level_chain, ref_p);
+ pph_stream_write_tree_vec (ob, bl->dead_vars_from_for, ref_p);
+ lto_output_chain (ob, bl->statement_list, ref_p);
+ lto_output_sleb128_stream (ob->main_stream, bl->binding_depth);
+
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, bl->kind, 4);
+ bp_pack_value (&bp, bl->keep, 1);
+ bp_pack_value (&bp, bl->more_cleanups_ok, 1);
+ bp_pack_value (&bp, bl->have_cleanups, 1);
+ lto_output_bitpack (&bp);
+}
+
+
+/* Write all the fields of c_language_function instance CLF to OB. If
+ REF_P is true, all tree fields should be written as references. */
+
+static void
+pph_stream_write_c_language_function (struct output_block *ob,
+ struct c_language_function *clf,
+ bool ref_p)
+{
+ if (clf == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ lto_output_tree_or_ref (ob, clf->x_stmt_tree.x_cur_stmt_list, ref_p);
+ lto_output_sleb128_stream (ob->main_stream,
+ clf->x_stmt_tree.stmts_are_full_exprs_p);
+}
+
+
+/* Write all the fields of language_function instance LF to OB. If
+ REF_P is true, all tree fields should be written as references. */
+
+static void
+pph_stream_write_language_function (struct output_block *ob,
+ struct language_function *lf,
+ bool ref_p)
+{
+ struct bitpack_d bp;
+
+ if (lf == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ pph_stream_write_c_language_function (ob, &lf->base, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_cdtor_label, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_current_class_ptr, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_current_class_ref, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_eh_spec_block, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_in_charge_parm, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_vtt_parm, ref_p);
+ lto_output_tree_or_ref (ob, lf->x_return_value, ref_p);
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, lf->x_returns_value, 1);
+ bp_pack_value (&bp, lf->x_returns_null, 1);
+ bp_pack_value (&bp, lf->x_returns_abnormally, 1);
+ bp_pack_value (&bp, lf->x_in_function_try_handler, 1);
+ bp_pack_value (&bp, lf->x_in_base_initializer, 1);
+ bp_pack_value (&bp, lf->can_throw, 1);
+ lto_output_bitpack (&bp);
+
+ /* FIXME pph. We are not writing lf->x_named_labels. */
+
+ pph_stream_write_binding_level (ob, lf->bindings, ref_p);
+ pph_stream_write_tree_vec (ob, lf->x_local_names, ref_p);
+
+ /* FIXME pph. We are not writing lf->extern_decl_map. */
+}
+
+
+/* Write all the fields of lang_decl_fn instance LDF to OB. If REF_P
+ is true, all tree fields should be written as references. */
+
+static void
+pph_stream_write_ld_fn (struct output_block *ob, struct lang_decl_fn *ldf,
+ bool ref_p)
+{
+ struct bitpack_d bp;
+
+ if (ldf == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, ldf->operator_code, 16);
+ bp_pack_value (&bp, ldf->global_ctor_p, 1);
+ bp_pack_value (&bp, ldf->global_dtor_p, 1);
+ bp_pack_value (&bp, ldf->constructor_attr, 1);
+ bp_pack_value (&bp, ldf->destructor_attr, 1);
+ bp_pack_value (&bp, ldf->assignment_operator_p, 1);
+ bp_pack_value (&bp, ldf->static_function, 1);
+ bp_pack_value (&bp, ldf->pure_virtual, 1);
+ bp_pack_value (&bp, ldf->defaulted_p, 1);
+ bp_pack_value (&bp, ldf->has_in_charge_parm_p, 1);
+ bp_pack_value (&bp, ldf->has_vtt_parm_p, 1);
+ bp_pack_value (&bp, ldf->pending_inline_p, 1);
+ bp_pack_value (&bp, ldf->nonconverting, 1);
+ bp_pack_value (&bp, ldf->thunk_p, 1);
+ bp_pack_value (&bp, ldf->this_thunk_p, 1);
+ bp_pack_value (&bp, ldf->hidden_friend_p, 1);
+ lto_output_bitpack (&bp);
+
+ lto_output_tree_or_ref (ob, ldf->befriending_classes, ref_p);
+ lto_output_tree_or_ref (ob, ldf->context, ref_p);
+
+ if (ldf->thunk_p == 0)
+ lto_output_tree_or_ref (ob, ldf->u5.cloned_function, ref_p);
+ else if (ldf->thunk_p == 1)
+ lto_output_sleb128_stream (ob->main_stream, ldf->u5.fixed_offset);
+ else
+ gcc_unreachable ();
+
+ if (ldf->pending_inline_p == 1)
+ pth_save_token_cache (ldf->u.pending_inline_info, pph_get_ob_stream (ob));
+ else if (ldf->pending_inline_p == 0)
+ pph_stream_write_language_function (ob, ldf->u.saved_language_function,
+ ref_p);
+}
+
+
+/* Write all the fields of lang_decl_ns instance LDNS to OB. If REF_P
+ is true, all tree fields should be written as references. */
+
+static void
+pph_stream_write_ld_ns (struct output_block *ob, struct lang_decl_ns *ldns,
+ bool ref_p)
+{
+ struct cp_binding_level *level;
+
+ if (ldns == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ level = ldns->level;
+ pph_stream_write_binding_level (ob, level, ref_p);
+}
+
+
+/* Write all the fields of lang_decl_parm instance LDP to OB. If REF_P
+ is true, all tree fields should be written as references. */
+
+static void
+pph_stream_write_ld_parm (struct output_block *ob, struct lang_decl_parm *ldp)
+{
+ if (ldp == NULL)
+ {
+ pph_output_uint (pph_get_ob_stream (ob), 0);
+ return;
+ }
+
+ lto_output_sleb128_stream (ob->main_stream, ldp->level);
+ lto_output_sleb128_stream (ob->main_stream, ldp->index);
+}
+
+
+/* Write all the lang-specific data in DECL to OB. REF_P is true if
+ the trees referenced in lang-specific fields should be written as
+ references. */
+
+static void
+pph_stream_write_lang_specific_data (struct output_block *ob,
+ tree decl, bool ref_p)
+{
+ struct lang_decl *ld;
+ struct lang_decl_base *ldb;
+
+ gcc_assert (DECL_P (decl) && DECL_LANG_SPECIFIC (decl));
+
+ ld = DECL_LANG_SPECIFIC (decl);
+ ldb = &ld->u.base;
+
+ /* Write all the fields in lang_decl_base. */
+ pph_stream_write_ld_base (ob, ldb);
+
+ if (ldb->selector == 0)
+ {
+ /* Write all the fields in lang_decl_min. */
+ pph_stream_write_ld_min (ob, &ld->u.min, ref_p);
+ }
+ else if (ldb->selector == 1)
+ {
+ /* Write all the fields in lang_decl_fn. */
+ pph_stream_write_ld_fn (ob, &ld->u.fn, ref_p);
+ }
+ else if (ldb->selector == 2)
+ {
+ /* Write all the fields in lang_decl_ns. */
+ pph_stream_write_ld_ns (ob, &ld->u.ns, ref_p);
+ }
+ else if (ldb->selector == 3)
+ {
+ /* Write all the fields in lang_decl_parm. */
+ pph_stream_write_ld_parm (ob, &ld->u.parm);
+ }
+ else
+ gcc_unreachable ();
}
@@ -145,8 +560,14 @@ pph_stream_init_write (pph_stream *stream)
static void
pph_stream_write_tree (struct output_block *ob, tree expr, bool ref_p)
{
- if (TREE_CODE (expr) == FUNCTION_DECL)
- lto_output_tree_or_ref (ob, DECL_SAVED_TREE (expr), ref_p);
+ if (DECL_P (expr))
+ {
+ if (DECL_LANG_SPECIFIC (expr))
+ pph_stream_write_lang_specific_data (ob, expr, ref_p);
+
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ lto_output_tree_or_ref (ob, DECL_SAVED_TREE (expr), ref_p);
+ }
else if (TREE_CODE (expr) == STATEMENT_LIST)
{
tree_stmt_iterator i;
@@ -222,6 +643,17 @@ pph_stream_unpack_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED,
}
+/* Return true if T can be emitted in the decls table as a reference.
+ This should only handle C++ specific declarations. All others are
+ handled by the LTO streamer directly. */
+
+static bool
+pph_indexable_with_decls_p (tree t)
+{
+ return TREE_CODE (t) == TEMPLATE_DECL;
+}
+
+
/* Initialize all the streamer hooks used for streaming ASTs. */
static void
@@ -233,6 +665,7 @@ pph_stream_hooks_init (void)
h->write_tree = pph_stream_write_tree;
h->read_tree = pph_stream_read_tree;
h->pack_value_fields = pph_stream_pack_value_fields;
+ h->indexable_with_decls_p = pph_indexable_with_decls_p;
h->unpack_value_fields = pph_stream_unpack_value_fields;
}
@@ -274,15 +707,13 @@ pph_stream_begin_section (const char *name ATTRIBUTE_UNUSED)
/* Callback for lang_hooks.lto.append_data. Write LEN bytes from DATA
- into current_pph_file. BLOCK is currently unused, but this hook is
- required to free it. */
+ into current_pph_file. BLOCK is currently unused. */
static void
-pph_stream_write (const void *data, size_t len, void *block)
+pph_stream_write (const void *data, size_t len, void *block ATTRIBUTE_UNUSED)
{
if (data)
fwrite (data, len, 1, current_pph_file);
- free (block);
}
@@ -92,6 +92,9 @@ void pph_stream_trace_bytes (pph_stream *, const void *, size_t);
void pph_stream_trace_string (pph_stream *, const char *);
void pph_stream_trace_string_with_length (pph_stream *, const char *, unsigned);
+/* In pph.c. FIXME move these to pph-streamer.c. */
+struct cp_token_cache;
+extern void pth_save_token_cache (struct cp_token_cache *, pph_stream *);
/* Inline functions. */
@@ -195,4 +198,22 @@ pph_input_tree (pph_stream *stream ATTRIBUTE_UNUSED)
return t;
}
+/* Return the PPH stream object associated with output block OB. */
+
+static inline pph_stream *
+pph_get_ob_stream (struct output_block *ob)
+{
+ /* FIXME pph - Do not overload OB fields this way. */
+ return ((pph_stream *) ob->cfg_stream);
+}
+
+/* Set the PPH stream object F associated with output block OB. */
+
+static inline void
+pph_set_ob_stream (struct output_block *ob, pph_stream *f)
+{
+ /* FIXME pph - Do not overload OB fields this way. */
+ ob->cfg_stream = (struct lto_output_stream *) f;
+}
+
#endif /* GCC_CP_PPH_STREAMER_H */
@@ -427,84 +427,44 @@ pth_save_token (cp_token *token, pph_stream *f)
pth_save_token_value (f, token);
}
+/* Save all the tokens in CACHE to PPH stream F. */
-/* Write header information for IMAGE to STREAM. */
-
-static void
-pth_write_header (pth_image *image, pph_stream *stream)
+void
+pth_save_token_cache (cp_token_cache *cache, pph_stream *f)
{
- const char *id = pth_id_str ();
+ unsigned i, num;
+ cp_token *tok;
- if (!image->digest_computed_p)
+ if (cache == NULL)
{
- pth_get_md5_digest (image->fname, image->digest);
- image->digest_computed_p = true;
+ pph_output_uint (f, 0);
+ return;
}
- pph_output_bytes (stream, id, strlen (id));
- pph_output_bytes (stream, image->digest, DIGEST_LEN);
-}
-
-
-/* Pretty print the previous macro definitions in the table of IDENTIFIERS to
- the STREAM. */
-
-static void
-pph_print_macro_defs_before (pph_stream *stream, cpp_idents_used *identifiers)
-{
- unsigned int idx;
-
- for (idx = 0; idx < identifiers->num_entries; ++idx)
- {
- cpp_ident_use *entry = identifiers->entries + idx;
- const char *ident = entry->ident_str;
- const char *before = entry->before_str;
+ for (num = 0, tok = cache->first; tok != cache->last; tok++)
+ num++;
- if (before)
- {
- pph_output_string (stream, "#define ");
- pph_output_string (stream, ident);
- pph_output_string (stream, before);
- }
- else
- {
- pph_output_string (stream, "#undef ");
- pph_output_string (stream, ident);
- }
- }
+ pph_output_uint (f, num);
+ for (i = 0, tok = cache->first; i < num; tok++, i++)
+ pth_save_token (tok, f);
}
-/* Pretty print the subsequent macro definitions in the table of IDENTIFIERS to
- the STREAM. */
+/* Write header information for IMAGE to STREAM. */
static void
-pph_print_macro_defs_after (pph_stream *stream, cpp_idents_used *identifiers)
+pth_write_header (pth_image *image, pph_stream *stream)
{
- unsigned int idx;
+ const char *id = pth_id_str ();
- for (idx = 0; idx < identifiers->num_entries; ++idx)
+ if (!image->digest_computed_p)
{
- cpp_ident_use *entry = identifiers->entries + idx;
- const char *ident = entry->ident_str;
- const char *before = entry->before_str;
- const char *after = entry->after_str;
-
- if (before != after)
- {
- if (after && (!before || strcmp (after, before) != 0))
- {
- pph_output_string (stream, "#define ");
- pph_output_string (stream, ident);
- pph_output_string (stream, after);
- }
- else if (before)
- {
- pph_output_string (stream, "#undef ");
- pph_output_string (stream, ident);
- }
- }
+ pth_get_md5_digest (image->fname, image->digest);
+ image->digest_computed_p = true;
}
+
+ pph_output_bytes (stream, id, strlen (id));
+ pph_output_bytes (stream, image->digest, DIGEST_LEN);
}
@@ -1841,105 +1801,13 @@ pth_file_change (cpp_reader *reader, const struct line_map *map)
}
-/* Write PPH output file. */
-
-typedef void (*pph_write_format)(pph_stream *stream, tree decl, int flags);
-
-/* Forward declarations to break cyclic references. */
-static void
-pph_write_namespace (pph_stream *, tree, pph_write_format, int);
-
-
-/* Write symbol to PPH output file like C. */
-
-static void
-pph_write_print (pph_stream *stream, tree decl, int flags ATTRIBUTE_UNUSED)
-{
- pph_output_tree (stream, decl);
-}
-
-
-/* Write symbol to PPH output file as a dump. */
-
-static void
-pph_write_dump (pph_stream *stream, tree decl, int flags)
-{
- dump_node (decl, flags, stream->file);
-}
-
-
-/* Write symbol to PPH output file. */
-
-static void
-pph_write_symbol (pph_stream *stream, tree decl, pph_write_format fmt,
- int flags)
-{
- if (TREE_CODE (decl) == NAMESPACE_DECL)
- pph_write_namespace (stream, decl, fmt, flags);
- else if (!DECL_IS_BUILTIN (decl))
- fmt (stream, decl, flags);
-}
-
-
-/* Write namespace to PPH output file. */
-
-typedef void (*declvisitor)(pph_stream *, tree, pph_write_format, int);
-
-static void
-pph_write_namespace_1 (declvisitor vtor, pph_stream *stream, tree decl,
- pph_write_format fmt, int flags)
-{
- tree prior = TREE_CHAIN (decl);
- if (prior)
- pph_write_namespace_1 (vtor, stream, prior, fmt, flags);
- vtor (stream, decl, fmt, flags);
-}
-
-static void
-pph_write_namespace (pph_stream *stream, tree decl, pph_write_format fmt,
- int flags)
-{
- struct cp_binding_level *level = NAMESPACE_LEVEL (decl);
- decl = level->namespaces;
- if (decl)
- pph_write_namespace_1 (pph_write_namespace, stream, decl, fmt, flags);
- decl = level->names;
- if (decl)
- pph_write_namespace_1 (pph_write_symbol, stream, decl, fmt, flags);
-}
-
-
/* Write PPH output symbols and IDENTS_USED to STREAM as an object. */
static void
-pph_write_file_object (pph_stream *stream, cpp_idents_used *idents_used)
+pph_write_file_contents (pph_stream *stream, cpp_idents_used *idents_used)
{
- int flags = 0;
pth_save_identifiers (idents_used, stream);
- pph_write_namespace (stream, global_namespace, pph_write_print, flags);
-}
-
-
-/* Write PPH output symbols and IDENTS_USED to STREAM as a pretty summary. */
-
-static void
-pph_write_file_summary (pph_stream *stream, cpp_idents_used *idents_used)
-{
- int flags = 0;
- pph_print_macro_defs_before (stream, idents_used);
- pph_write_namespace (stream, global_namespace, pph_write_print, flags);
- pph_print_macro_defs_after (stream, idents_used);
-}
-
-
-/* Write PPH output symbols and IDENTS_USED to STREAM as a textual dump. */
-
-static void
-pph_write_file_dump (pph_stream *stream, cpp_idents_used *idents_used)
-{
- int flags = TDF_UID | TDF_LINENO;
- pth_dump_identifiers (stream->file, idents_used);
- pph_write_namespace (stream, global_namespace, pph_write_dump, flags);
+ pph_output_tree (stream, global_namespace);
}
@@ -1959,17 +1827,8 @@ pph_write_file (void)
fatal_error ("Cannot open PPH file for writing: %s: %m", pph_out_file);
idents_used = cpp_lt_capture (parse_in);
+ pph_write_file_contents (stream, &idents_used);
- if (flag_pph_fmt == 0)
- pph_write_file_object (stream, &idents_used);
- else if (flag_pph_fmt == 1)
- pph_write_file_summary (stream, &idents_used);
- else if (flag_pph_fmt == 2)
- pph_write_file_dump (stream, &idents_used);
- else
- error ("unrecognized -fpph-fmt value: %d", flag_pph_fmt);
-
- /*FIX pph: double free or corruption: cpp_lt_idents_destroy (&idents_used); */
pph_stream_close (stream);
}
@@ -2016,10 +1875,10 @@ report_validation_error (const char *filename,
}
-/* Read PPH FILENAME from STREAM as an object. */
+/* Read contents of PPH file in STREAM. */
static void
-pph_file_read_object (const char *filename, pph_stream *stream)
+pph_read_file_contents (pph_stream *stream)
{
bool verified;
cpp_ident_use *bad_use;
@@ -2027,24 +1886,26 @@ pph_file_read_object (const char *filename, pph_stream *stream)
cpp_idents_used idents_used;
pth_load_identifiers (&idents_used, stream);
+
/*FIXME pph: This validation is weak. */
verified = cpp_lt_verify_1 (parse_in, &idents_used, &bad_use, &cur_def, true);
if (!verified)
- report_validation_error (filename, bad_use->ident_str, cur_def,
+ report_validation_error (stream->name, bad_use->ident_str, cur_def,
bad_use->before_str, bad_use->after_str);
- /* FIX pph: We cannot replay the macro definitions
+
+ /* FIXME pph: We cannot replay the macro definitions
as long as we are still reading the actual file.
cpp_lt_replay (parse_in, &idents_used);
*/
- /* FIX pph: Also read decls. */
+ /* FIXME pph: Also read decls. */
}
/* Read PPH file. */
static void
-pph_file_read (const char *filename)
+pph_read_file (const char *filename)
{
pph_stream *stream;
@@ -2055,8 +1916,7 @@ pph_file_read (const char *filename)
if (!stream)
fatal_error ("Cannot open PPH file for reading: %s: %m", filename);
- if (flag_pph_fmt == 0)
- pph_file_read_object (filename, stream);
+ pph_read_file_contents (stream);
pph_stream_close (stream);
}
@@ -2113,7 +1973,7 @@ pph_include_handler (cpp_reader *reader,
pph_file = query_pph_include_map (name);
if (pph_file != NULL && !cpp_included_before (reader, name, input_location))
- pph_file_read (pph_file);
+ pph_read_file (pph_file);
}
@@ -1889,7 +1889,7 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
/* Read a chain of tree nodes from input block IB. DATA_IN contains
tables and descriptors for the file being read. */
-static tree
+tree
lto_input_chain (struct lto_input_block *ib, struct data_in *data_in)
{
int i, count;
@@ -718,9 +718,20 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
break;
default:
- /* No other node is indexable, so it should have been handled
- by lto_output_tree. */
- gcc_unreachable ();
+ /* See if streamer hooks allows this node to be indexable with
+ VAR_DECLs. */
+ if (streamer_hooks ()->indexable_with_decls_p
+ && streamer_hooks ()->indexable_with_decls_p (expr))
+ {
+ output_record_start (ob, LTO_global_decl_ref);
+ lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
+ }
+ else
+ {
+ /* No other node is indexable, so it should have been
+ handled by lto_output_tree. */
+ gcc_unreachable ();
+ }
}
}
@@ -742,7 +753,7 @@ lto_output_tree_or_ref (struct output_block *ob, tree expr, bool ref_p)
to write to. REF_P is true if chain elements should be emitted
as references. */
-static void
+void
lto_output_chain (struct output_block *ob, tree t, bool ref_p)
{
int i, count;
@@ -1166,12 +1177,6 @@ lto_output_tree_pointers (struct output_block *ob, tree expr, bool 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);
@@ -1181,21 +1186,6 @@ lto_output_tree_pointers (struct output_block *ob, tree expr, bool 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 ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
- sorry ("gimple bytecode streams do not support the optimization attribute");
-
if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
lto_output_ts_target_option (ob, expr);
@@ -823,6 +823,8 @@ lto_is_streamable (tree expr)
&& code != BIND_EXPR
&& code != WITH_CLEANUP_EXPR
&& code != STATEMENT_LIST
+ && code != OMP_CLAUSE
+ && code != OPTIMIZATION_NODE
&& (code == CASE_LABEL_EXPR
|| code == DECL_EXPR
|| TREE_CODE_CLASS (code) != tcc_statement);
@@ -86,6 +86,11 @@ typedef struct lto_streamer_hooks {
are as in lto_read_tree. */
void (*read_tree) (struct lto_input_block *, struct data_in *, tree);
+ /* Called by lto_output_tree_ref to determine if the given tree node
+ should be emitted as a reference to the table of declarations
+ (the same table that holds VAR_DECLs). */
+ bool (*indexable_with_decls_p) (tree);
+
/* Called by pack_value_fields to store any non-pointer fields
in the tree structure. The arguments are as in pack_value_fields. */
void (*pack_value_fields) (struct bitpack_d *, tree);
@@ -913,6 +918,7 @@ extern lto_streamer_hooks *streamer_hooks_init (void);
extern void lto_input_cgraph (struct lto_file_decl_data *, const char *);
extern void lto_reader_init (void);
extern tree lto_input_tree (struct lto_input_block *, struct data_in *);
+extern tree lto_input_chain (struct lto_input_block *, struct data_in *);
extern void lto_input_function_body (struct lto_file_decl_data *, tree,
const char *);
extern void lto_input_constructors_and_inits (struct lto_file_decl_data *,
@@ -934,6 +940,7 @@ extern struct output_block *create_output_block (enum lto_section_type);
extern void destroy_output_block (struct output_block *);
extern void lto_output_tree (struct output_block *, tree, bool);
extern void lto_output_tree_or_ref (struct output_block *, tree, bool);
+extern void lto_output_chain (struct output_block *, tree, bool);
extern void produce_asm (struct output_block *ob, tree fn);
extern void lto_output_string (struct output_block *,
struct lto_output_stream *,