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)
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/>. */
23 #include "coretypes.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"
31 #include "tree-pass.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. */
45 pph_stream_pack_value_fields (struct bitpack_d
*bp
, tree 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. */
83 pph_stream_init_write (pph_stream
*stream
)
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
93 stream
->ob
->sdata
= (void *) stream
;
97 /* Callback for lang_hooks.lto.begin_section. Open file NAME. */
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. */
109 pph_stream_write (const void *data
, size_t len
, void *block ATTRIBUTE_UNUSED
)
112 fwrite (data
, len
, 1, current_pph_file
);
116 /* Callback for lang_hooks.lto.end_section. */
119 pph_stream_end_section (void)
124 /* Write the header for the PPH file represented by STREAM. */
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. */
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
,
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. */
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
);
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. */
201 pph_start_record (pph_stream
*stream
, void *data
)
205 pph_output_uchar (stream
, PPH_RECORD_START
);
210 pph_output_uchar (stream
, PPH_RECORD_END
);
216 /* Write all the fields in lang_decl_base instance LDB to OB. */
219 pph_stream_write_ld_base (pph_stream
*stream
, struct lang_decl_base
*ldb
)
223 if (!pph_start_record (stream
, ldb
))
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. */
247 pph_stream_write_ld_min (pph_stream
*stream
, struct lang_decl_min
*ldm
,
250 if (!pph_start_record (stream
, ldm
))
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
);
265 /* Write all the trees in gc VEC V to STREAM. REF_P is true if the
266 trees should be written as references. */
269 pph_stream_write_tree_vec (pph_stream
*stream
, VEC(tree
,gc
) *v
, bool ref_p
)
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. */
284 pph_stream_write_qual_use_vec (pph_stream
*stream
,
285 VEC(qualified_typedef_usage_t
,gc
) *v
, bool ref_p
)
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. */
309 pph_stream_write_cxx_binding_1 (pph_stream
*stream
, cxx_binding
*cb
, bool ref_p
)
313 if (!pph_start_record (stream
, cb
))
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. */
330 pph_stream_write_cxx_binding (pph_stream
*stream
, cxx_binding
*cb
, bool ref_p
)
332 unsigned num_bindings
;
335 if (!pph_start_record (stream
, cb
))
338 for (num_bindings
= 0, prev
= cb
->previous
; prev
; prev
= prev
->previous
)
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. */
355 pph_stream_write_class_binding (pph_stream
*stream
, cp_class_binding
*cb
,
358 if (!pph_start_record (stream
, cb
))
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. */
370 pph_stream_write_label_binding (pph_stream
*stream
, cp_label_binding
*lb
,
373 if (!pph_start_record (stream
, lb
))
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. */
386 pph_output_chain_filtered (pph_stream
*stream
, tree first
, bool ref_p
,
387 enum chain_filter filter
)
392 /* Special case. If the caller wants no filtering, it is much
393 faster to just call pph_output_chain directly. */
396 pph_output_chain (stream
, first
, ref_p
);
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
))
407 pph_output_uint (stream
, count
);
409 /* Output all the nodes that match the filter. */
410 for (t
= first
; t
; t
= TREE_CHAIN (t
))
414 /* Apply filters to T. */
415 if (filter
== NO_BUILTINS
&& DECL_P (t
) && DECL_IS_BUILTIN (t
))
418 /* Clear TREE_CHAIN to avoid blindly recursing into the rest
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. */
434 pph_stream_write_binding_level (pph_stream
*stream
, struct cp_binding_level
*bl
,
438 cp_class_binding
*cs
;
439 cp_label_binding
*sl
;
442 if (!pph_start_record (stream
, bl
))
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. */
484 pph_stream_write_c_language_function (pph_stream
*stream
,
485 struct c_language_function
*clf
,
488 if (!pph_start_record (stream
, clf
))
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. */
500 pph_stream_write_language_function (pph_stream
*stream
,
501 struct language_function
*lf
,
506 if (!pph_start_record (stream
, lf
))
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. */
539 pph_stream_write_ld_fn (pph_stream
*stream
, struct lang_decl_fn
*ldf
,
544 if (!pph_start_record (stream
, ldf
))
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
);
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
,
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. */
588 pph_stream_write_ld_ns (pph_stream
*stream
, struct lang_decl_ns
*ldns
,
591 struct cp_binding_level
*level
;
593 if (!pph_start_record (stream
, ldns
))
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. */
605 pph_stream_write_ld_parm (pph_stream
*stream
, struct lang_decl_parm
*ldp
)
607 if (!pph_start_record (stream
, ldp
))
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
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
))
629 /* Write all the fields in lang_decl_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
);
658 /* Write all the fields in lang_type_header instance LTH to STREAM. */
661 pph_stream_write_lang_type_header (pph_stream
*stream
,
662 struct lang_type_header
*lth
)
666 if (!pph_start_record (stream
, lth
))
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. */
685 pph_stream_write_tree_pair_vec (pph_stream
*stream
, VEC(tree_pair_s
,gc
) *v
,
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. */
704 pph_stream_write_sorted_fields_type (pph_stream
*stream
,
705 struct sorted_fields_type
*sft
, bool ref_p
)
709 if (!pph_start_record (stream
, sft
))
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
723 pph_stream_write_lang_type_class (pph_stream
*stream
,
724 struct lang_type_class
*ltc
, bool ref_p
)
728 if (!pph_start_record (stream
, ltc
))
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. */
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
))
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
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
))
827 pph_stream_write_lang_type_header (stream
, <
->u
.h
);
828 if (lt
->u
.h
.is_lang_type_class
)
829 pph_stream_write_lang_type_class (stream
, <
->u
.c
, ref_p
);
831 pph_stream_write_lang_type_ptrmem (stream
, <
->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. */
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. */
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
:
868 pph_output_tree_or_ref_1 (stream
, DECL_INITIAL (expr
), ref_p
, 3);
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
);
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);
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);
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);
908 case FIXED_POINT_TYPE
:
920 pph_stream_write_lang_type (stream
, expr
, ref_p
);
923 case QUAL_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);
930 case BOUND_TEMPLATE_TEMPLATE_PARM
:
932 case TEMPLATE_TEMPLATE_PARM
:
933 case TEMPLATE_TYPE_PARM
:
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. */
946 tree_stmt_iterator i
;
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
))
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);
971 /* tcc_exceptional */
974 pph_output_tree_or_ref_1 (stream
, OVL_CURRENT (expr
), ref_p
, 3);
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);
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);
994 pph_stream_write_qual_use_vec (stream
,
995 TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (expr
), ref_p
);
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
1011 /* TREES ALREADY HANDLED */
1013 /* tcc_declaration */
1015 case TRANSLATION_UNIT_DECL
:
1017 /* tcc_exceptional */
1025 /* TREES UNIMPLEMENTED */
1027 /* tcc_declaration */
1031 case TYPE_ARGUMENT_PACK
:
1032 case TYPE_PACK_EXPANSION
:
1033 case UNBOUND_CLASS_TEMPLATE
:
1044 case RANGE_FOR_STMT
:
1051 /* tcc_expression */
1056 case VEC_DELETE_EXPR
:
1060 case EMPTY_CLASS_EXPR
:
1061 case TEMPLATE_ID_EXPR
:
1062 case PSEUDO_DTOR_EXPR
:
1066 case NON_DEPENDENT_EXPR
:
1067 case CTOR_INITIALIZER
:
1068 case MUST_NOT_THROW_EXPR
:
1075 case AT_ENCODE_EXPR
:
1077 case NONTYPE_ARGUMENT_PACK
:
1078 case EXPR_PACK_EXPANSION
:
1083 case REINTERPRET_CAST_EXPR
:
1084 case CONST_CAST_EXPR
:
1085 case STATIC_CAST_EXPR
:
1086 case DYNAMIC_CAST_EXPR
:
1088 case UNARY_PLUS_EXPR
:
1102 case AGGR_INIT_EXPR
:
1104 /* tcc_exceptional */
1108 case ARGUMENT_PACK_SELECT
:
1112 if (flag_pph_untree
)
1113 fprintf (pph_logfile
, "PPH: unimplemented tree node %s\n",
1114 tree_code_name
[TREE_CODE (expr
)]);
1117 /* TREES UNRECOGNIZED */
1120 if (flag_pph_untree
)
1121 fprintf (pph_logfile
, "PPH: unrecognized tree node %s\n",
1122 tree_code_name
[TREE_CODE (expr
)]);