See comments inline. > + > +/* PPH write/read */ > + > + > +/* Emit a tinst_level list TINST to STREAM. */ > + > +static void > +pph_out_tinst_level (pph_stream *stream, struct tinst_level *tinst) > +{ > + int count; > + struct tinst_level *cur; > + > + /* Count the number of items. */ > + for (cur = tinst; cur != NULL; cur = cur->next ) > + ++count; > + > + /* Now emit them. */ > + pph_out_uint (stream, count); > + for (cur = tinst; cur != NULL; cur = cur->next ) > + { > + pph_out_tree (stream, cur->decl); > + pph_out_location (stream, cur->locus); > + pph_out_uint (stream, cur->errors); > + pph_out_uint (stream, cur->in_system_header_p); > + } > +} > + > +/* Dump a tinst_level list TINST to STREAM. */ > + > +static void > +pph_dump_tinst_level (FILE *stream, struct tinst_level *tinst) > +{ > + int count; > + struct tinst_level *cur; > + > + /* Count the number of items. */ > + for (cur = tinst; cur != NULL; cur = cur->next ) > + ++count; > + > + /* Now dump them. */ > + fprintf (stream, "%d tinst_levels\n", count ); > + for (cur = tinst; cur != NULL; cur = cur->next ) > + { > + pph_dump_tree_name (stream, cur->decl, 0); > + /* pph_dump_location (stream, cur->locus); */ > + fprintf (stream, "%d errors, ", cur->errors ); > + fprintf (stream, "%d in system header\n", cur->in_system_header_p ); > + } > +} > + > +/* Load a tinst_level list. */ > + > +static struct tinst_level * > +pph_in_tinst_level (pph_stream *stream) > +{ > + struct tinst_level *last = NULL; > + unsigned count = pph_in_uint (stream); > + /* FIXME pph: This leaves the list in reverse order. Issue? */ > + for (; count > 0; --count) > + { > + struct tinst_level *cur = ggc_alloc_tinst_level (); > + cur->next = last;
- cur->next = last; + if(last) + last->next = cur; > + cur->decl = pph_in_tree (stream); > + cur->locus = pph_in_location (stream); > + cur->errors = pph_in_uint (stream); > + cur->in_system_header_p = pph_in_uint (stream); > + last = cur; > + } if (last) last->next = NULL; > + return last; > +} > + If you do the changes above, the list won't be in reverse order. Also if you do it as I did in pph_in_cxx_binding, using the cache markers, you do need to output count, you can simply use the cache mechanism which will know how to output/input NULL (I used that in pph_in/out_cxx_binding). > + > +/* Load and merge a spec_entry TABLE from STREAM. */ > + > +static void > +pph_in_spec_entry_htab (pph_stream *stream, htab_t *table) > +{ > + spec_entry **slot = NULL; This variable is shadowed by.... > + unsigned count = pph_in_uint (stream); > + if (flag_pph_debug >= 2) > + fprintf (stderr, "loading %d spec_entries\n", count ); > + for (; count > 0; --count) > + { > + hashval_t hash; > + spec_entry **slot; ...this one?? > + struct spec_entry *se = ggc_alloc_spec_entry (); > + se->tmpl = pph_in_tree (stream); > + se->args = pph_in_tree (stream); > + se->spec = pph_in_tree (stream); > + hash = hash_specialization (se); > + slot = htab_find_slot_with_hash (*table, se, hash, INSERT); > + *slot = se; > + } > +} > + > Index: gcc/cp/pph-streamer.c > =================================================================== > --- gcc/cp/pph-streamer.c (revision 176778) > +++ gcc/cp/pph-streamer.c (working copy) > @@ -169,6 +169,7 @@ enum pph_trace_type > PPH_TRACE_UINT, > PPH_TRACE_BYTES, > PPH_TRACE_STRING, > + PPH_TRACE_LOCATION, > PPH_TRACE_CHAIN, > PPH_TRACE_BITPACK > }; > @@ -244,6 +245,14 @@ pph_trace (pph_stream *stream, const voi > fprintf (pph_logfile, ", NULL_STRING"); > break; > > + case PPH_TRACE_LOCATION: > + if (data) > + fprintf (pph_logfile, ", value=%.*s", > + (int) nbytes, (const char *) data); > + else > + fprintf (pph_logfile, ", NULL_LOCATION"); > + break; > + > case PPH_TRACE_CHAIN: > { > const_tree t = (const_tree) data; > @@ -316,6 +325,26 @@ pph_trace_string_with_length (pph_stream > } > > > +/* Show tracing information for location_t LOC on STREAM. */ > + > +void > +pph_trace_location (pph_stream *stream, location_t loc) > +{ > + char dec[10]; /* ten digits per file line number */ > + expanded_location xloc = expand_location (loc); > + size_t flen = strlen (xloc.file); > + size_t mlen = flen + 12; /* for : and 10 digits and \n */ > + size_t llen; > + char *str = xmalloc (mlen); > + > + strcpy (str, xloc.file); > + str[flen] = ':'; > + sprintf (str + flen + 1, "%d", xloc.line); > + llen = strlen (str); > + pph_trace (stream, str, llen, PPH_TRACE_LOCATION); > +} > + > + > /* Show tracing information for a tree chain starting with T on STREAM. */ > > void > Index: gcc/cp/pph-streamer.h > =================================================================== > --- gcc/cp/pph-streamer.h (revision 176778) > +++ gcc/cp/pph-streamer.h (working copy) > @@ -142,6 +142,7 @@ void pph_trace_uint (pph_stream *, unsig > void pph_trace_bytes (pph_stream *, const void *, size_t); > void pph_trace_string (pph_stream *, const char *); > void pph_trace_string_with_length (pph_stream *, const char *, unsigned); > +void pph_trace_location (pph_stream *, location_t); > void pph_trace_chain (pph_stream *, tree); > void pph_trace_bitpack (pph_stream *, struct bitpack_d *); > void pph_cache_insert_at (pph_stream *, void *, unsigned); > @@ -170,6 +171,13 @@ tree pph_alloc_tree (enum tree_code, str > struct data_in *); > void pph_read_file (const char *); > > +/* In pt.c. */ > +extern void pph_out_pending_templates_list (pph_stream *stream); > +extern void pph_in_pending_templates_list (pph_stream *stream); > +extern void pph_out_spec_entry_tables (pph_stream *stream); > +extern void pph_in_spec_entry_tables (pph_stream *stream); > + > + > /* Inline functions. */ > > /* Output AST T to STREAM. This function is the primary interface. */ > @@ -280,6 +288,15 @@ pph_out_tree_VEC (pph_stream *stream, VE > } > #endif > > +/* Write location LOC of length to STREAM. */ > +static inline void > +pph_out_location (pph_stream *stream, location_t loc) > +{ > + if (flag_pph_tracer >= 4) > + pph_trace_location (stream, loc); > + lto_output_location (stream->ob, loc); > +} > + > /* Write a chain of ASTs to STREAM starting with FIRST. */ > static inline void > pph_out_chain (pph_stream *stream, tree first) > @@ -341,6 +358,16 @@ pph_in_string (pph_stream *stream) > return s; > } > > +/* Read and return a location_t from STREAM. */ > +static inline location_t > +pph_in_location (pph_stream *stream) > +{ > + location_t loc = lto_input_location (stream->ib, stream->data_in); > + if (flag_pph_tracer >= 4) > + pph_trace_location (stream, loc); > + return loc; > +} > + I was actually going to create pph_in/out_location. I will need to make them a streamer_hook so that all calls to lto_input/output_location actually are redirected to those when lto wants to in/out a source_location. Of course it would no longer call lto_input/output_location, rather it would output the source_location directly, and apply the calculated offset (discussed in "Linemap and pph") on the way in. It's great that you implemented a tracer for this as it will be easy for me to debug my implementation of this, thanks! Is there anything you implementation depends on I should be careful about, from what I see, it doesn't look like it (as long as the source_location you get back from pph_in_location are correct). > /* Load an AST from STREAM. Return the corresponding tree. */ > static inline tree > pph_in_tree (pph_stream *stream) > Index: gcc/cp/pph-streamer-out.c > =================================================================== > --- gcc/cp/pph-streamer-out.c (revision 176778) > +++ gcc/cp/pph-streamer-out.c (working copy) > @@ -1245,6 +1245,10 @@ pph_write_file_contents (pph_stream *str > globals should be fields in struct cp_parser. */ > pph_out_tree (stream, keyed_classes); > pph_out_tree_vec (stream, unemitted_tinfo_decls); > + > + pph_out_pending_templates_list (stream); > + pph_out_spec_entry_tables (stream); > + > pph_out_tree (stream, static_aggregates); > > /* Emit the symbol table. */ > Index: gcc/lto-streamer-out.c > =================================================================== > --- gcc/lto-streamer-out.c (revision 176778) > +++ gcc/lto-streamer-out.c (working copy) > @@ -644,7 +644,7 @@ lto_output_location_bitpack (struct bitp > When bitpack is handy, it is more space effecient to call > lto_output_location_bitpack with existing bitpack. */ > > -static void > +void > lto_output_location (struct output_block *ob, location_t loc) > { > struct bitpack_d bp = bitpack_create (ob->main_stream); > Index: gcc/lto-streamer-in.c > =================================================================== > --- gcc/lto-streamer-in.c (revision 176778) > +++ gcc/lto-streamer-in.c (working copy) > @@ -333,7 +333,7 @@ lto_input_location_bitpack (struct data_ > > /* Read a location from input block IB. */ > > -static location_t > +location_t > lto_input_location (struct lto_input_block *ib, struct data_in *data_in) > { > struct bitpack_d bp; > Index: gcc/lto-streamer.h > =================================================================== > --- gcc/lto-streamer.h (revision 176778) > +++ gcc/lto-streamer.h (working copy) > @@ -977,6 +977,9 @@ extern void lto_data_in_delete (struct d > extern const char *lto_input_string (struct data_in *, > struct lto_input_block *); > extern void lto_input_data_block (struct lto_input_block *, void *, size_t); > +extern location_t lto_input_location (struct lto_input_block *ib, > + struct data_in *data_in); > + > extern void gimple_streamer_reader_init (void); > > > @@ -1001,6 +1004,7 @@ void lto_output_string (struct output_bl > void lto_output_string_with_length (struct output_block *, > struct lto_output_stream *, const char *, > unsigned int, bool); > +extern void lto_output_location (struct output_block *ob, location_t loc); > > lto_input/ouput will again no longer need to be extern when I make my patch for pph to handle those differently, I will make sure (remind me if I don't) to remove this change. -Gab