Oranize the PPH tree switch into tcc_* chunks, in each of four sections:
[official-gcc.git] / gcc / cp / pph-streamer-out.c
blob82319da6d371d3fac0851221e69c71d2d22ee655
1 /* Routines for writing PPH data.
2 Copyright (C) 2011 Free Software Foundation, Inc.
3 Contributed by Diego Novillo <dnovillo@google.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "langhooks.h"
26 #include "tree-iterator.h"
27 #include "tree-pretty-print.h"
28 #include "lto-streamer.h"
29 #include "pph-streamer.h"
30 #include "pph.h"
31 #include "tree-pass.h"
32 #include "version.h"
33 #include "cppbuiltin.h"
35 /* FIXME pph. This holds the FILE handle for the current PPH file
36 that we are writing. It is necessary because the LTO callbacks do
37 not allow passing a FILE handle to them. */
38 static FILE *current_pph_file = NULL;
41 /* Callback for packing value fields in ASTs. BP is the bitpack
42 we are packing into. EXPR is the tree to pack. */
44 void
45 pph_stream_pack_value_fields (struct bitpack_d *bp, tree expr)
47 if (TYPE_P (expr))
49 bp_pack_value (bp, TYPE_LANG_FLAG_0 (expr), 1);
50 bp_pack_value (bp, TYPE_LANG_FLAG_1 (expr), 1);
51 bp_pack_value (bp, TYPE_LANG_FLAG_2 (expr), 1);
52 bp_pack_value (bp, TYPE_LANG_FLAG_3 (expr), 1);
53 bp_pack_value (bp, TYPE_LANG_FLAG_4 (expr), 1);
54 bp_pack_value (bp, TYPE_LANG_FLAG_5 (expr), 1);
55 bp_pack_value (bp, TYPE_LANG_FLAG_6 (expr), 1);
57 else if (DECL_P (expr))
59 bp_pack_value (bp, DECL_LANG_FLAG_0 (expr), 1);
60 bp_pack_value (bp, DECL_LANG_FLAG_1 (expr), 1);
61 bp_pack_value (bp, DECL_LANG_FLAG_2 (expr), 1);
62 bp_pack_value (bp, DECL_LANG_FLAG_3 (expr), 1);
63 bp_pack_value (bp, DECL_LANG_FLAG_4 (expr), 1);
64 bp_pack_value (bp, DECL_LANG_FLAG_5 (expr), 1);
65 bp_pack_value (bp, DECL_LANG_FLAG_6 (expr), 1);
66 bp_pack_value (bp, DECL_LANG_FLAG_7 (expr), 1);
67 bp_pack_value (bp, DECL_LANG_FLAG_8 (expr), 1);
70 bp_pack_value (bp, TREE_LANG_FLAG_0 (expr), 1);
71 bp_pack_value (bp, TREE_LANG_FLAG_1 (expr), 1);
72 bp_pack_value (bp, TREE_LANG_FLAG_2 (expr), 1);
73 bp_pack_value (bp, TREE_LANG_FLAG_3 (expr), 1);
74 bp_pack_value (bp, TREE_LANG_FLAG_4 (expr), 1);
75 bp_pack_value (bp, TREE_LANG_FLAG_5 (expr), 1);
76 bp_pack_value (bp, TREE_LANG_FLAG_6 (expr), 1);
80 /* Initialize buffers and tables in STREAM for writing. */
82 void
83 pph_stream_init_write (pph_stream *stream)
85 lto_writer_init ();
86 stream->out_state = lto_new_out_decl_state ();
87 lto_push_out_decl_state (stream->out_state);
88 stream->decl_state_stream = XCNEW (struct lto_output_stream);
89 stream->ob = create_output_block (LTO_section_decls);
91 /* Associate STREAM with STREAM->OB so we can recover it from the
92 streamer hooks. */
93 stream->ob->sdata = (void *) stream;
97 /* Callback for lang_hooks.lto.begin_section. Open file NAME. */
99 static void
100 pph_stream_begin_section (const char *name ATTRIBUTE_UNUSED)
105 /* Callback for lang_hooks.lto.append_data. Write LEN bytes from DATA
106 into current_pph_file. BLOCK is currently unused. */
108 static void
109 pph_stream_write (const void *data, size_t len, void *block ATTRIBUTE_UNUSED)
111 if (data)
112 fwrite (data, len, 1, current_pph_file);
116 /* Callback for lang_hooks.lto.end_section. */
118 static void
119 pph_stream_end_section (void)
124 /* Write the header for the PPH file represented by STREAM. */
126 static void
127 pph_stream_write_header (pph_stream *stream)
129 pph_file_header header;
130 struct lto_output_stream header_stream;
131 int major, minor, patchlevel;
133 /* Collect version information. */
134 parse_basever (&major, &minor, &patchlevel);
135 gcc_assert (major == (char) major);
136 gcc_assert (minor == (char) minor);
137 gcc_assert (patchlevel == (char) patchlevel);
139 /* Write the header for the PPH file. */
140 memset (&header, 0, sizeof (header));
141 strcpy (header.id_str, pph_id_str);
142 header.major_version = (char) major;
143 header.minor_version = (char) minor;
144 header.patchlevel = (char) patchlevel;
145 header.strtab_size = stream->ob->string_stream->total_size;
147 memset (&header_stream, 0, sizeof (header_stream));
148 lto_output_data_stream (&header_stream, &header, sizeof (header));
149 lto_write_stream (&header_stream);
153 /* Write the body of the PPH file represented by STREAM. */
155 static void
156 pph_stream_write_body (pph_stream *stream)
158 /* Write the string table. */
159 lto_write_stream (stream->ob->string_stream);
161 /* Write out the physical representation for every AST in all the
162 streams in STREAM->OUT_STATE. */
163 lto_output_decl_state_streams (stream->ob, stream->out_state);
165 /* Now write the vector of all AST references. */
166 lto_output_decl_state_refs (stream->ob, stream->decl_state_stream,
167 stream->out_state);
169 /* Finally, physically write all the streams. */
170 lto_write_stream (stream->ob->main_stream);
174 /* Flush all the in-memory buffers for STREAM to disk. */
176 void
177 pph_stream_flush_buffers (pph_stream *stream)
179 gcc_assert (current_pph_file == NULL);
180 current_pph_file = stream->file;
182 /* Redirect the LTO basic I/O langhooks. */
183 lang_hooks.lto.begin_section = pph_stream_begin_section;
184 lang_hooks.lto.append_data = pph_stream_write;
185 lang_hooks.lto.end_section = pph_stream_end_section;
187 /* Write the state buffers built by pph_output_*() calls. */
188 lto_begin_section (stream->name, false);
189 pph_stream_write_header (stream);
190 pph_stream_write_body (stream);
191 lto_end_section ();
192 current_pph_file = NULL;
196 /* Start a new record in STREAM for data in DATA. If DATA is NULL,
197 write an end-of-record marker and return false. Otherwise, write a
198 start-of-record marker and return true. */
200 static inline bool
201 pph_start_record (pph_stream *stream, void *data)
203 if (data)
205 pph_output_uchar (stream, PPH_RECORD_START);
206 return true;
208 else
210 pph_output_uchar (stream, PPH_RECORD_END);
211 return false;
216 /* Write all the fields in lang_decl_base instance LDB to OB. */
218 static void
219 pph_stream_write_ld_base (pph_stream *stream, struct lang_decl_base *ldb)
221 struct bitpack_d bp;
223 if (!pph_start_record (stream, ldb))
224 return;
226 bp = bitpack_create (stream->ob->main_stream);
227 bp_pack_value (&bp, ldb->selector, 16);
228 bp_pack_value (&bp, ldb->language, 4);
229 bp_pack_value (&bp, ldb->use_template, 2);
230 bp_pack_value (&bp, ldb->not_really_extern, 1);
231 bp_pack_value (&bp, ldb->initialized_in_class, 1);
232 bp_pack_value (&bp, ldb->repo_available_p, 1);
233 bp_pack_value (&bp, ldb->threadprivate_or_deleted_p, 1);
234 bp_pack_value (&bp, ldb->anticipated_p, 1);
235 bp_pack_value (&bp, ldb->friend_attr, 1);
236 bp_pack_value (&bp, ldb->template_conv_p, 1);
237 bp_pack_value (&bp, ldb->odr_used, 1);
238 bp_pack_value (&bp, ldb->u2sel, 1);
239 pph_output_bitpack (stream, &bp);
243 /* Write all the fields in lang_decl_min instance LDM to STREAM. If REF_P
244 is true, all tree fields should be written as references. */
246 static void
247 pph_stream_write_ld_min (pph_stream *stream, struct lang_decl_min *ldm,
248 bool ref_p)
250 if (!pph_start_record (stream, ldm))
251 return;
253 gcc_assert (ldm->base.selector == 0);
255 pph_output_tree_or_ref_1 (stream, ldm->template_info, ref_p, 1);
256 if (ldm->base.u2sel == 0)
257 pph_output_tree_or_ref_1 (stream, ldm->u2.access, ref_p, 1);
258 else if (ldm->base.u2sel == 1)
259 pph_output_uint (stream, ldm->u2.discriminator);
260 else
261 gcc_unreachable ();
265 /* Write all the trees in gc VEC V to STREAM. REF_P is true if the
266 trees should be written as references. */
268 void
269 pph_stream_write_tree_vec (pph_stream *stream, VEC(tree,gc) *v, bool ref_p)
271 unsigned i;
272 tree t;
274 pph_output_uint (stream, VEC_length (tree, v));
275 for (i = 0; VEC_iterate (tree, v, i, t); i++)
276 pph_output_tree_or_ref (stream, t, ref_p);
280 /* Write all the qualified_typedef_usage_t in VEC V to STREAM.
281 REF_P is true if the trees should be written as references. */
283 static void
284 pph_stream_write_qual_use_vec (pph_stream *stream,
285 VEC(qualified_typedef_usage_t,gc) *v, bool ref_p)
287 unsigned i;
288 qualified_typedef_usage_t *q;
290 pph_output_uint (stream, VEC_length (qualified_typedef_usage_t, v));
291 for (i = 0; VEC_iterate (qualified_typedef_usage_t, v, i, q); i++)
293 pph_output_tree_or_ref (stream, q->typedef_decl, ref_p);
294 pph_output_tree_or_ref (stream, q->context, ref_p);
295 /* FIXME pph: also write location? */
300 /* Forward declaration to break cyclic dependencies. */
301 static void pph_stream_write_binding_level (pph_stream *,
302 struct cp_binding_level *, bool);
305 /* Helper for pph_stream_write_cxx_binding. STREAM, CB and REF_P are as in
306 pph_stream_write_cxx_binding. */
308 static void
309 pph_stream_write_cxx_binding_1 (pph_stream *stream, cxx_binding *cb, bool ref_p)
311 struct bitpack_d bp;
313 if (!pph_start_record (stream, cb))
314 return;
316 pph_output_tree_or_ref (stream, cb->value, ref_p);
317 pph_output_tree_or_ref (stream, cb->type, ref_p);
318 pph_stream_write_binding_level (stream, cb->scope, ref_p);
319 bp = bitpack_create (stream->ob->main_stream);
320 bp_pack_value (&bp, cb->value_is_inherited, 1);
321 bp_pack_value (&bp, cb->is_local, 1);
322 pph_output_bitpack (stream, &bp);
326 /* Write all the fields of cxx_binding instance CB to STREAM. REF_P is
327 true if the tree fields should be written as references. */
329 static void
330 pph_stream_write_cxx_binding (pph_stream *stream, cxx_binding *cb, bool ref_p)
332 unsigned num_bindings;
333 cxx_binding *prev;
335 if (!pph_start_record (stream, cb))
336 return;
338 for (num_bindings = 0, prev = cb->previous; prev; prev = prev->previous)
339 num_bindings++;
341 /* Write the list of previous bindings. */
342 pph_output_uint (stream, num_bindings);
343 for (prev = cb->previous; prev; prev = prev->previous)
344 pph_stream_write_cxx_binding_1 (stream, prev, ref_p);
346 /* Write the current binding at the end. */
347 pph_stream_write_cxx_binding_1 (stream, cb, ref_p);
351 /* Write all the fields of cp_class_binding instance CB to STREAM. REF_P
352 is true if the tree fields should be written as references. */
354 static void
355 pph_stream_write_class_binding (pph_stream *stream, cp_class_binding *cb,
356 bool ref_p)
358 if (!pph_start_record (stream, cb))
359 return;
361 pph_stream_write_cxx_binding (stream, &cb->base, ref_p);
362 pph_output_tree_or_ref (stream, cb->identifier, ref_p);
366 /* Write all the fields of cp_label_binding instance LB to STREAM. If
367 REF_P is true, tree fields will be written as references. */
369 static void
370 pph_stream_write_label_binding (pph_stream *stream, cp_label_binding *lb,
371 bool ref_p)
373 if (!pph_start_record (stream, lb))
374 return;
376 pph_output_tree_or_ref (stream, lb->label, ref_p);
377 pph_output_tree_or_ref (stream, lb->prev_value, ref_p);
381 /* Output a chain of nodes to STREAM starting with FIRST. Skip any
382 nodes that do not match FILTER. REF_P is true if nodes in the chain
383 should be emitted as references. */
385 void
386 pph_output_chain_filtered (pph_stream *stream, tree first, bool ref_p,
387 enum chain_filter filter)
389 unsigned count;
390 tree t;
392 /* Special case. If the caller wants no filtering, it is much
393 faster to just call pph_output_chain directly. */
394 if (filter == NONE)
396 pph_output_chain (stream, first, ref_p);
397 return;
400 /* Count all the nodes that match the filter. */
401 for (t = first, count = 0; t; t = TREE_CHAIN (t))
403 if (filter == NO_BUILTINS && DECL_P (t) && DECL_IS_BUILTIN (t))
404 continue;
405 count++;
407 pph_output_uint (stream, count);
409 /* Output all the nodes that match the filter. */
410 for (t = first; t; t = TREE_CHAIN (t))
412 tree saved_chain;
414 /* Apply filters to T. */
415 if (filter == NO_BUILTINS && DECL_P (t) && DECL_IS_BUILTIN (t))
416 continue;
418 /* Clear TREE_CHAIN to avoid blindly recursing into the rest
419 of the list. */
420 saved_chain = TREE_CHAIN (t);
421 TREE_CHAIN (t) = NULL_TREE;
423 pph_output_tree_or_ref_1 (stream, t, ref_p, 2);
425 TREE_CHAIN (t) = saved_chain;
430 /* Write all the fields of cp_binding_level instance BL to STREAM. If
431 REF_P is true, tree fields will be written as references. */
433 static void
434 pph_stream_write_binding_level (pph_stream *stream, struct cp_binding_level *bl,
435 bool ref_p)
437 unsigned i;
438 cp_class_binding *cs;
439 cp_label_binding *sl;
440 struct bitpack_d bp;
442 if (!pph_start_record (stream, bl))
443 return;
445 pph_output_chain_filtered (stream, bl->names, ref_p, NO_BUILTINS);
446 pph_output_uint (stream, bl->names_size);
447 pph_output_chain_filtered (stream, bl->namespaces, ref_p, NO_BUILTINS);
449 pph_stream_write_tree_vec (stream, bl->static_decls, ref_p);
451 pph_output_chain_filtered (stream, bl->usings, ref_p, NO_BUILTINS);
452 pph_output_chain_filtered (stream, bl->using_directives, ref_p, NO_BUILTINS);
454 pph_output_uint (stream, VEC_length (cp_class_binding, bl->class_shadowed));
455 for (i = 0; VEC_iterate (cp_class_binding, bl->class_shadowed, i, cs); i++)
456 pph_stream_write_class_binding (stream, cs, ref_p);
458 pph_output_tree_or_ref (stream, bl->type_shadowed, ref_p);
460 pph_output_uint (stream, VEC_length (cp_label_binding, bl->shadowed_labels));
461 for (i = 0; VEC_iterate (cp_label_binding, bl->shadowed_labels, i, sl); i++)
462 pph_stream_write_label_binding (stream, sl, ref_p);
464 pph_output_chain (stream, bl->blocks, ref_p);
465 pph_output_tree_or_ref (stream, bl->this_entity, ref_p);
466 pph_stream_write_binding_level (stream, bl->level_chain, ref_p);
467 pph_stream_write_tree_vec (stream, bl->dead_vars_from_for, ref_p);
468 pph_output_chain (stream, bl->statement_list, ref_p);
469 pph_output_uint (stream, bl->binding_depth);
471 bp = bitpack_create (stream->ob->main_stream);
472 bp_pack_value (&bp, bl->kind, 4);
473 bp_pack_value (&bp, bl->keep, 1);
474 bp_pack_value (&bp, bl->more_cleanups_ok, 1);
475 bp_pack_value (&bp, bl->have_cleanups, 1);
476 pph_output_bitpack (stream, &bp);
480 /* Write all the fields of c_language_function instance CLF to STREAM. If
481 REF_P is true, all tree fields should be written as references. */
483 static void
484 pph_stream_write_c_language_function (pph_stream *stream,
485 struct c_language_function *clf,
486 bool ref_p)
488 if (!pph_start_record (stream, clf))
489 return;
491 pph_output_tree_or_ref (stream, clf->x_stmt_tree.x_cur_stmt_list, ref_p);
492 pph_output_uint (stream, clf->x_stmt_tree.stmts_are_full_exprs_p);
496 /* Write all the fields of language_function instance LF to STREAM. If
497 REF_P is true, all tree fields should be written as references. */
499 static void
500 pph_stream_write_language_function (pph_stream *stream,
501 struct language_function *lf,
502 bool ref_p)
504 struct bitpack_d bp;
506 if (!pph_start_record (stream, lf))
507 return;
509 pph_stream_write_c_language_function (stream, &lf->base, ref_p);
510 pph_output_tree_or_ref (stream, lf->x_cdtor_label, ref_p);
511 pph_output_tree_or_ref (stream, lf->x_current_class_ptr, ref_p);
512 pph_output_tree_or_ref (stream, lf->x_current_class_ref, ref_p);
513 pph_output_tree_or_ref (stream, lf->x_eh_spec_block, ref_p);
514 pph_output_tree_or_ref (stream, lf->x_in_charge_parm, ref_p);
515 pph_output_tree_or_ref (stream, lf->x_vtt_parm, ref_p);
516 pph_output_tree_or_ref (stream, lf->x_return_value, ref_p);
517 bp = bitpack_create (stream->ob->main_stream);
518 bp_pack_value (&bp, lf->x_returns_value, 1);
519 bp_pack_value (&bp, lf->x_returns_null, 1);
520 bp_pack_value (&bp, lf->x_returns_abnormally, 1);
521 bp_pack_value (&bp, lf->x_in_function_try_handler, 1);
522 bp_pack_value (&bp, lf->x_in_base_initializer, 1);
523 bp_pack_value (&bp, lf->can_throw, 1);
524 pph_output_bitpack (stream, &bp);
526 /* FIXME pph. We are not writing lf->x_named_labels. */
528 pph_stream_write_binding_level (stream, lf->bindings, ref_p);
529 pph_stream_write_tree_vec (stream, lf->x_local_names, ref_p);
531 /* FIXME pph. We are not writing lf->extern_decl_map. */
535 /* Write all the fields of lang_decl_fn instance LDF to STREAM. If REF_P
536 is true, all tree fields should be written as references. */
538 static void
539 pph_stream_write_ld_fn (pph_stream *stream, struct lang_decl_fn *ldf,
540 bool ref_p)
542 struct bitpack_d bp;
544 if (!pph_start_record (stream, ldf))
545 return;
547 bp = bitpack_create (stream->ob->main_stream);
548 bp_pack_value (&bp, ldf->operator_code, 16);
549 bp_pack_value (&bp, ldf->global_ctor_p, 1);
550 bp_pack_value (&bp, ldf->global_dtor_p, 1);
551 bp_pack_value (&bp, ldf->constructor_attr, 1);
552 bp_pack_value (&bp, ldf->destructor_attr, 1);
553 bp_pack_value (&bp, ldf->assignment_operator_p, 1);
554 bp_pack_value (&bp, ldf->static_function, 1);
555 bp_pack_value (&bp, ldf->pure_virtual, 1);
556 bp_pack_value (&bp, ldf->defaulted_p, 1);
557 bp_pack_value (&bp, ldf->has_in_charge_parm_p, 1);
558 bp_pack_value (&bp, ldf->has_vtt_parm_p, 1);
559 bp_pack_value (&bp, ldf->pending_inline_p, 1);
560 bp_pack_value (&bp, ldf->nonconverting, 1);
561 bp_pack_value (&bp, ldf->thunk_p, 1);
562 bp_pack_value (&bp, ldf->this_thunk_p, 1);
563 bp_pack_value (&bp, ldf->hidden_friend_p, 1);
564 pph_output_bitpack (stream, &bp);
566 pph_output_tree_or_ref (stream, ldf->befriending_classes, ref_p);
567 pph_output_tree_or_ref (stream, ldf->context, ref_p);
569 if (ldf->thunk_p == 0)
570 pph_output_tree_or_ref (stream, ldf->u5.cloned_function, ref_p);
571 else if (ldf->thunk_p == 1)
572 pph_output_uint (stream, ldf->u5.fixed_offset);
573 else
574 gcc_unreachable ();
576 if (ldf->pending_inline_p == 1)
577 pth_save_token_cache (ldf->u.pending_inline_info, stream);
578 else if (ldf->pending_inline_p == 0)
579 pph_stream_write_language_function (stream, ldf->u.saved_language_function,
580 ref_p);
584 /* Write all the fields of lang_decl_ns instance LDNS to STREAM. If REF_P
585 is true, all tree fields should be written as references. */
587 static void
588 pph_stream_write_ld_ns (pph_stream *stream, struct lang_decl_ns *ldns,
589 bool ref_p)
591 struct cp_binding_level *level;
593 if (!pph_start_record (stream, ldns))
594 return;
596 level = ldns->level;
597 pph_stream_write_binding_level (stream, level, ref_p);
601 /* Write all the fields of lang_decl_parm instance LDP to STREAM. If REF_P
602 is true, all tree fields should be written as references. */
604 static void
605 pph_stream_write_ld_parm (pph_stream *stream, struct lang_decl_parm *ldp)
607 if (!pph_start_record (stream, ldp))
608 return;
610 pph_output_uint (stream, ldp->level);
611 pph_output_uint (stream, ldp->index);
615 /* Write all the lang-specific data in DECL to STREAM. REF_P is true if
616 the trees referenced in lang-specific fields should be written as
617 references. */
619 static void
620 pph_stream_write_lang_specific (pph_stream *stream, tree decl, bool ref_p)
622 struct lang_decl *ld;
623 struct lang_decl_base *ldb;
625 ld = DECL_LANG_SPECIFIC (decl);
626 if (!pph_start_record (stream, ld))
627 return;
629 /* Write all the fields in lang_decl_base. */
630 ldb = &ld->u.base;
631 pph_stream_write_ld_base (stream, ldb);
633 if (ldb->selector == 0)
635 /* Write all the fields in lang_decl_min. */
636 pph_stream_write_ld_min (stream, &ld->u.min, ref_p);
638 else if (ldb->selector == 1)
640 /* Write all the fields in lang_decl_fn. */
641 pph_stream_write_ld_fn (stream, &ld->u.fn, ref_p);
643 else if (ldb->selector == 2)
645 /* Write all the fields in lang_decl_ns. */
646 pph_stream_write_ld_ns (stream, &ld->u.ns, ref_p);
648 else if (ldb->selector == 3)
650 /* Write all the fields in lang_decl_parm. */
651 pph_stream_write_ld_parm (stream, &ld->u.parm);
653 else
654 gcc_unreachable ();
658 /* Write all the fields in lang_type_header instance LTH to STREAM. */
660 static void
661 pph_stream_write_lang_type_header (pph_stream *stream,
662 struct lang_type_header *lth)
664 struct bitpack_d bp;
666 if (!pph_start_record (stream, lth))
667 return;
669 bp = bitpack_create (stream->ob->main_stream);
670 bp_pack_value (&bp, lth->is_lang_type_class, 1);
671 bp_pack_value (&bp, lth->has_type_conversion, 1);
672 bp_pack_value (&bp, lth->has_copy_ctor, 1);
673 bp_pack_value (&bp, lth->has_default_ctor, 1);
674 bp_pack_value (&bp, lth->const_needs_init, 1);
675 bp_pack_value (&bp, lth->ref_needs_init, 1);
676 bp_pack_value (&bp, lth->has_const_copy_assign, 1);
677 pph_output_bitpack (stream, &bp);
681 /* Write the vector V of tree_pair_s instances to STREAM. REF_P is
682 true if the trees should be written as references. */
684 static void
685 pph_stream_write_tree_pair_vec (pph_stream *stream, VEC(tree_pair_s,gc) *v,
686 bool ref_p)
688 unsigned i;
689 tree_pair_s *p;
691 pph_output_uint (stream, VEC_length (tree_pair_s, v));
692 for (i = 0; VEC_iterate (tree_pair_s, v, i, p); i++)
694 pph_output_tree_or_ref (stream, p->purpose, ref_p);
695 pph_output_tree_or_ref (stream, p->value, ref_p);
700 /* Write a struct sorted_fields_type instance SFT to STREAM. REF_P is
701 true if the tree nodes should be written as references. */
703 static void
704 pph_stream_write_sorted_fields_type (pph_stream *stream,
705 struct sorted_fields_type *sft, bool ref_p)
707 int i;
709 if (!pph_start_record (stream, sft))
710 return;
712 pph_output_uint (stream, sft->len);
713 for (i = 0; i < sft->len; i++)
714 pph_output_tree_or_ref (stream, sft->elts[i], ref_p);
718 /* Write all the fields in lang_type_class instance LTC to STREAM.
719 REF_P is true if all the trees in the structure should be written
720 as references. */
722 static void
723 pph_stream_write_lang_type_class (pph_stream *stream,
724 struct lang_type_class *ltc, bool ref_p)
726 struct bitpack_d bp;
728 if (!pph_start_record (stream, ltc))
729 return;
731 pph_output_uchar (stream, ltc->align);
733 bp = bitpack_create (stream->ob->main_stream);
734 bp_pack_value (&bp, ltc->has_mutable, 1);
735 bp_pack_value (&bp, ltc->com_interface, 1);
736 bp_pack_value (&bp, ltc->non_pod_class, 1);
737 bp_pack_value (&bp, ltc->nearly_empty_p, 1);
738 bp_pack_value (&bp, ltc->user_align, 1);
739 bp_pack_value (&bp, ltc->has_copy_assign, 1);
740 bp_pack_value (&bp, ltc->has_new, 1);
741 bp_pack_value (&bp, ltc->has_array_new, 1);
742 bp_pack_value (&bp, ltc->gets_delete, 2);
743 bp_pack_value (&bp, ltc->interface_only, 1);
744 bp_pack_value (&bp, ltc->interface_unknown, 1);
745 bp_pack_value (&bp, ltc->contains_empty_class_p, 1);
746 bp_pack_value (&bp, ltc->anon_aggr, 1);
747 bp_pack_value (&bp, ltc->non_zero_init, 1);
748 bp_pack_value (&bp, ltc->empty_p, 1);
749 bp_pack_value (&bp, ltc->vec_new_uses_cookie, 1);
750 bp_pack_value (&bp, ltc->declared_class, 1);
751 bp_pack_value (&bp, ltc->diamond_shaped, 1);
752 bp_pack_value (&bp, ltc->repeated_base, 1);
753 bp_pack_value (&bp, ltc->being_defined, 1);
754 bp_pack_value (&bp, ltc->java_interface, 1);
755 bp_pack_value (&bp, ltc->debug_requested, 1);
756 bp_pack_value (&bp, ltc->fields_readonly, 1);
757 bp_pack_value (&bp, ltc->use_template, 2);
758 bp_pack_value (&bp, ltc->ptrmemfunc_flag, 1);
759 bp_pack_value (&bp, ltc->was_anonymous, 1);
760 bp_pack_value (&bp, ltc->lazy_default_ctor, 1);
761 bp_pack_value (&bp, ltc->lazy_copy_ctor, 1);
762 bp_pack_value (&bp, ltc->lazy_copy_assign, 1);
763 bp_pack_value (&bp, ltc->lazy_destructor, 1);
764 bp_pack_value (&bp, ltc->has_const_copy_ctor, 1);
765 bp_pack_value (&bp, ltc->has_complex_copy_ctor, 1);
766 bp_pack_value (&bp, ltc->has_complex_copy_assign, 1);
767 bp_pack_value (&bp, ltc->non_aggregate, 1);
768 bp_pack_value (&bp, ltc->has_complex_dflt, 1);
769 bp_pack_value (&bp, ltc->has_list_ctor, 1);
770 bp_pack_value (&bp, ltc->non_std_layout, 1);
771 bp_pack_value (&bp, ltc->is_literal, 1);
772 bp_pack_value (&bp, ltc->lazy_move_ctor, 1);
773 bp_pack_value (&bp, ltc->lazy_move_assign, 1);
774 bp_pack_value (&bp, ltc->has_complex_move_ctor, 1);
775 bp_pack_value (&bp, ltc->has_complex_move_assign, 1);
776 bp_pack_value (&bp, ltc->has_constexpr_ctor, 1);
777 pph_output_bitpack (stream, &bp);
779 pph_output_tree_or_ref (stream, ltc->primary_base, ref_p);
780 pph_stream_write_tree_pair_vec (stream, ltc->vcall_indices, ref_p);
781 pph_output_tree_or_ref (stream, ltc->vtables, ref_p);
782 pph_output_tree_or_ref (stream, ltc->typeinfo_var, ref_p);
783 pph_stream_write_tree_vec (stream, ltc->vbases, ref_p);
784 if (pph_start_record (stream, ltc->nested_udts))
785 pph_stream_write_binding_table (stream, ltc->nested_udts, ref_p);
786 pph_output_tree_or_ref (stream, ltc->as_base, ref_p);
787 pph_stream_write_tree_vec (stream, ltc->pure_virtuals, ref_p);
788 pph_output_tree_or_ref (stream, ltc->friend_classes, ref_p);
789 pph_stream_write_tree_vec (stream, ltc->methods, ref_p);
790 pph_output_tree_or_ref (stream, ltc->key_method, ref_p);
791 pph_output_tree_or_ref (stream, ltc->decl_list, ref_p);
792 pph_output_tree_or_ref (stream, ltc->template_info, ref_p);
793 pph_output_tree_or_ref (stream, ltc->befriending_classes, ref_p);
794 pph_output_tree_or_ref (stream, ltc->objc_info, ref_p);
795 pph_stream_write_sorted_fields_type (stream, ltc->sorted_fields, ref_p);
796 pph_output_tree_or_ref (stream, ltc->lambda_expr, ref_p);
800 /* Write struct lang_type_ptrmem instance LTP to STREAM. If REF_P is
801 true, all fields in the structure are written as references. */
803 static void
804 pph_stream_write_lang_type_ptrmem (pph_stream *stream, struct
805 lang_type_ptrmem *ltp, bool ref_p)
807 if (!pph_start_record (stream, ltp))
808 return;
810 pph_output_tree_or_ref (stream, ltp->record, ref_p);
814 /* Write all the lang-specific fields of TYPE to STREAM. REF_P is
815 true if tree nodes in the structure need to be written as
816 references. */
818 static void
819 pph_stream_write_lang_type (pph_stream *stream, tree type, bool ref_p)
821 struct lang_type *lt;
823 lt = TYPE_LANG_SPECIFIC (type);
824 if (!pph_start_record (stream, lt))
825 return;
827 pph_stream_write_lang_type_header (stream, &lt->u.h);
828 if (lt->u.h.is_lang_type_class)
829 pph_stream_write_lang_type_class (stream, &lt->u.c, ref_p);
830 else
831 pph_stream_write_lang_type_ptrmem (stream, &lt->u.ptrmem, ref_p);
835 /* Write header information for some AST nodes not handled by the
836 common streamer code. EXPR is the tree to write to output block
837 OB. If EXPR does not need to be handled specially, do nothing. */
839 void
840 pph_stream_output_tree_header (struct output_block *ob, tree expr)
842 pph_stream *stream = (pph_stream *) ob->sdata;
844 if (TREE_CODE (expr) == CALL_EXPR)
845 pph_output_uint (stream, call_expr_nargs (expr));
849 /* Callback for writing ASTs to a stream. This writes all the fields
850 that are not processed by default by the common tree pickler.
851 OB and REF_P are as in lto_write_tree. EXPR is the tree to write. */
853 void
854 pph_stream_write_tree (struct output_block *ob, tree expr, bool ref_p)
856 pph_stream *stream = (pph_stream *) ob->sdata;
858 switch (TREE_CODE (expr))
860 /* TREES NEEDING EXTRA WORK */
862 /* tcc_declaration */
864 case DEBUG_EXPR_DECL:
865 case IMPORTED_DECL:
866 case LABEL_DECL:
867 case RESULT_DECL:
868 pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3);
869 break;
871 case CONST_DECL:
872 case FIELD_DECL:
873 case NAMESPACE_DECL:
874 case PARM_DECL:
875 case USING_DECL:
876 case VAR_DECL:
877 /* FIXME pph: Should we merge DECL_INITIAL into lang_specific? */
878 pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3);
879 pph_stream_write_lang_specific (stream, expr, ref_p);
880 break;
882 case FUNCTION_DECL:
883 pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3);
884 pph_stream_write_lang_specific (stream, expr, ref_p);
885 pph_output_tree_or_ref_1 (stream, DECL_SAVED_TREE (expr), ref_p, 3);
886 break;
888 case TYPE_DECL:
889 pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3);
890 pph_stream_write_lang_specific (stream, expr, ref_p);
891 pph_output_tree_or_ref_1 (stream, DECL_ORIGINAL_TYPE (expr), ref_p, 3);
892 break;
894 case TEMPLATE_DECL:
895 pph_output_tree_or_ref_1 (stream, DECL_INITIAL (expr), ref_p, 3);
896 pph_stream_write_lang_specific (stream, expr, ref_p);
897 pph_output_tree_or_ref_1 (stream, DECL_TEMPLATE_RESULT (expr), ref_p, 3);
898 pph_output_tree_or_ref_1 (stream, DECL_TEMPLATE_PARMS (expr), ref_p, 3);
899 pph_output_tree_or_ref_1 (stream, DECL_CONTEXT (expr), ref_p, 3);
900 break;
902 /* tcc_type */
904 case ARRAY_TYPE:
905 case BOOLEAN_TYPE:
906 case COMPLEX_TYPE:
907 case ENUMERAL_TYPE:
908 case FIXED_POINT_TYPE:
909 case FUNCTION_TYPE:
910 case INTEGER_TYPE:
911 case LANG_TYPE:
912 case METHOD_TYPE:
913 case NULLPTR_TYPE:
914 case OFFSET_TYPE:
915 case POINTER_TYPE:
916 case REAL_TYPE:
917 case REFERENCE_TYPE:
918 case VECTOR_TYPE:
919 case VOID_TYPE:
920 pph_stream_write_lang_type (stream, expr, ref_p);
921 break;
923 case QUAL_UNION_TYPE:
924 case RECORD_TYPE:
925 case UNION_TYPE:
926 pph_stream_write_lang_type (stream, expr, ref_p);
927 pph_output_tree_or_ref_1 (stream, TYPE_BINFO (expr), ref_p, 3);
928 break;
930 case BOUND_TEMPLATE_TEMPLATE_PARM:
931 case DECLTYPE_TYPE:
932 case TEMPLATE_TEMPLATE_PARM:
933 case TEMPLATE_TYPE_PARM:
934 case TYPENAME_TYPE:
935 case TYPEOF_TYPE:
936 pph_stream_write_lang_type (stream, expr, ref_p);
937 pph_output_tree_or_ref_1 (stream, TYPE_CACHED_VALUES (expr), ref_p, 3);
938 /* Note that we are using TYPED_CACHED_VALUES for it access to
939 the generic .values field of types. */
940 break;
942 /* tcc_statement */
944 case STATEMENT_LIST:
946 tree_stmt_iterator i;
947 unsigned num_stmts;
949 /* Compute and write the number of statements in the list. */
950 for (num_stmts = 0, i = tsi_start (expr); !tsi_end_p (i); tsi_next (&i))
951 num_stmts++;
953 pph_output_uint (stream, num_stmts);
955 /* Write the statements. */
956 for (i = tsi_start (expr); !tsi_end_p (i); tsi_next (&i))
957 pph_output_tree_or_ref_1 (stream, tsi_stmt (i), ref_p, 3);
959 break;
961 /* tcc_expression */
963 /* tcc_unary */
965 /* tcc_vl_exp */
967 /* tcc_reference */
969 /* tcc_constant */
971 /* tcc_exceptional */
973 case OVERLOAD:
974 pph_output_tree_or_ref_1 (stream, OVL_CURRENT (expr), ref_p, 3);
975 break;
977 case IDENTIFIER_NODE:
979 struct lang_identifier *id = LANG_IDENTIFIER_CAST (expr);
980 pph_stream_write_cxx_binding (stream, id->namespace_bindings, ref_p);
981 pph_stream_write_cxx_binding (stream, id->bindings, ref_p);
982 pph_output_tree_or_ref_1 (stream, id->class_template_info, ref_p, 3);
983 pph_output_tree_or_ref_1 (stream, id->label_value, ref_p, 3);
985 break;
987 case BASELINK:
988 pph_output_tree_or_ref_1 (stream, BASELINK_BINFO (expr), ref_p, 3);
989 pph_output_tree_or_ref_1 (stream, BASELINK_FUNCTIONS (expr), ref_p, 3);
990 pph_output_tree_or_ref_1 (stream, BASELINK_ACCESS_BINFO (expr), ref_p, 3);
991 break;
993 case TEMPLATE_INFO:
994 pph_stream_write_qual_use_vec (stream,
995 TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr), ref_p);
996 break;
998 case TEMPLATE_PARM_INDEX:
1000 template_parm_index *p = TEMPLATE_PARM_INDEX_CAST (expr);
1001 pph_output_uint (stream, p->index);
1002 pph_output_uint (stream, p->level);
1003 pph_output_uint (stream, p->orig_level);
1004 pph_output_uint (stream, p->num_siblings);
1005 pph_output_tree_or_ref_1 (stream, p->decl, ref_p, 3);
1006 /* FIXME pph: Is TEMPLATE_PARM_PARAMETER_PACK using TREE_LANG_FLAG_0
1007 already handled? */
1009 break;
1011 /* TREES ALREADY HANDLED */
1013 /* tcc_declaration */
1015 case TRANSLATION_UNIT_DECL:
1017 /* tcc_exceptional */
1019 case TREE_BINFO:
1020 case TREE_LIST:
1021 case TREE_VEC:
1023 break;
1025 /* TREES UNIMPLEMENTED */
1027 /* tcc_declaration */
1029 /* tcc_type */
1031 case TYPE_ARGUMENT_PACK:
1032 case TYPE_PACK_EXPANSION:
1033 case UNBOUND_CLASS_TEMPLATE:
1035 /* tcc_statement */
1037 case USING_STMT:
1038 case TRY_BLOCK:
1039 case EH_SPEC_BLOCK:
1040 case HANDLER:
1041 case CLEANUP_STMT:
1042 case IF_STMT:
1043 case FOR_STMT:
1044 case RANGE_FOR_STMT:
1045 case WHILE_STMT:
1046 case DO_STMT:
1047 case BREAK_STMT:
1048 case CONTINUE_STMT:
1049 case SWITCH_STMT:
1051 /* tcc_expression */
1053 case NEW_EXPR:
1054 case VEC_NEW_EXPR:
1055 case DELETE_EXPR:
1056 case VEC_DELETE_EXPR:
1057 case TYPE_EXPR:
1058 case VEC_INIT_EXPR:
1059 case THROW_EXPR:
1060 case EMPTY_CLASS_EXPR:
1061 case TEMPLATE_ID_EXPR:
1062 case PSEUDO_DTOR_EXPR:
1063 case MODOP_EXPR:
1064 case DOTSTAR_EXPR:
1065 case TYPEID_EXPR:
1066 case NON_DEPENDENT_EXPR:
1067 case CTOR_INITIALIZER:
1068 case MUST_NOT_THROW_EXPR:
1069 case EXPR_STMT:
1070 case TAG_DEFN:
1071 case OFFSETOF_EXPR:
1072 case SIZEOF_EXPR:
1073 case ARROW_EXPR:
1074 case ALIGNOF_EXPR:
1075 case AT_ENCODE_EXPR:
1076 case STMT_EXPR:
1077 case NONTYPE_ARGUMENT_PACK:
1078 case EXPR_PACK_EXPANSION:
1080 /* tcc_unary */
1082 case CAST_EXPR:
1083 case REINTERPRET_CAST_EXPR:
1084 case CONST_CAST_EXPR:
1085 case STATIC_CAST_EXPR:
1086 case DYNAMIC_CAST_EXPR:
1087 case NOEXCEPT_EXPR:
1088 case UNARY_PLUS_EXPR:
1090 /* tcc_reference */
1092 case MEMBER_REF:
1093 case OFFSET_REF:
1094 case SCOPE_REF:
1096 /* tcc_constant */
1098 case PTRMEM_CST:
1100 /* tcc_vl_exp */
1102 case AGGR_INIT_EXPR:
1104 /* tcc_exceptional */
1106 case DEFAULT_ARG:
1107 case STATIC_ASSERT:
1108 case ARGUMENT_PACK_SELECT:
1109 case TRAIT_EXPR:
1110 case LAMBDA_EXPR:
1112 if (flag_pph_untree)
1113 fprintf (pph_logfile, "PPH: unimplemented tree node %s\n",
1114 tree_code_name[TREE_CODE (expr)]);
1115 break;
1117 /* TREES UNRECOGNIZED */
1119 default:
1120 if (flag_pph_untree)
1121 fprintf (pph_logfile, "PPH: unrecognized tree node %s\n",
1122 tree_code_name[TREE_CODE (expr)]);