xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-streamer-out.c (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino /* Routines for emitting trees to a file stream.
2e4b17023SJohn Marino 
3e4b17023SJohn Marino    Copyright 2011 Free Software Foundation, Inc.
4e4b17023SJohn Marino    Contributed by Diego Novillo <dnovillo@google.com>
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "diagnostic.h"
26e4b17023SJohn Marino #include "tree.h"
27e4b17023SJohn Marino #include "tree-streamer.h"
28e4b17023SJohn Marino #include "data-streamer.h"
29e4b17023SJohn Marino #include "streamer-hooks.h"
30e4b17023SJohn Marino 
31e4b17023SJohn Marino /* Output the STRING constant to the string
32e4b17023SJohn Marino    table in OB.  Then put the index onto the INDEX_STREAM.  */
33e4b17023SJohn Marino 
34e4b17023SJohn Marino void
streamer_write_string_cst(struct output_block * ob,struct lto_output_stream * index_stream,tree string)35e4b17023SJohn Marino streamer_write_string_cst (struct output_block *ob,
36e4b17023SJohn Marino 			   struct lto_output_stream *index_stream,
37e4b17023SJohn Marino 			   tree string)
38e4b17023SJohn Marino {
39e4b17023SJohn Marino   streamer_write_string_with_length (ob, index_stream,
40e4b17023SJohn Marino 				     string ? TREE_STRING_POINTER (string)
41e4b17023SJohn Marino 					    : NULL,
42e4b17023SJohn Marino 				     string ? TREE_STRING_LENGTH (string) : 0,
43e4b17023SJohn Marino 				     true);
44e4b17023SJohn Marino }
45e4b17023SJohn Marino 
46e4b17023SJohn Marino 
47e4b17023SJohn Marino /* Output the identifier ID to the string
48e4b17023SJohn Marino    table in OB.  Then put the index onto the INDEX_STREAM.  */
49e4b17023SJohn Marino 
50e4b17023SJohn Marino static void
write_identifier(struct output_block * ob,struct lto_output_stream * index_stream,tree id)51e4b17023SJohn Marino write_identifier (struct output_block *ob,
52e4b17023SJohn Marino 		   struct lto_output_stream *index_stream,
53e4b17023SJohn Marino 		   tree id)
54e4b17023SJohn Marino {
55e4b17023SJohn Marino   streamer_write_string_with_length (ob, index_stream,
56e4b17023SJohn Marino 				     IDENTIFIER_POINTER (id),
57e4b17023SJohn Marino 				     IDENTIFIER_LENGTH (id),
58e4b17023SJohn Marino 				     true);
59e4b17023SJohn Marino }
60e4b17023SJohn Marino 
61e4b17023SJohn Marino 
62e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_BASE structure of
63e4b17023SJohn Marino    expression EXPR into bitpack BP.  */
64e4b17023SJohn Marino 
65e4b17023SJohn Marino static void
pack_ts_base_value_fields(struct bitpack_d * bp,tree expr)66e4b17023SJohn Marino pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
67e4b17023SJohn Marino {
68e4b17023SJohn Marino   bp_pack_value (bp, TREE_CODE (expr), 16);
69e4b17023SJohn Marino   if (!TYPE_P (expr))
70e4b17023SJohn Marino     {
71e4b17023SJohn Marino       bp_pack_value (bp, TREE_SIDE_EFFECTS (expr), 1);
72e4b17023SJohn Marino       bp_pack_value (bp, TREE_CONSTANT (expr), 1);
73e4b17023SJohn Marino       bp_pack_value (bp, TREE_READONLY (expr), 1);
74e4b17023SJohn Marino 
75e4b17023SJohn Marino       /* TREE_PUBLIC is used on types to indicate that the type
76e4b17023SJohn Marino 	 has a TYPE_CACHED_VALUES vector.  This is not streamed out,
77e4b17023SJohn Marino 	 so we skip it here.  */
78e4b17023SJohn Marino       bp_pack_value (bp, TREE_PUBLIC (expr), 1);
79e4b17023SJohn Marino     }
80e4b17023SJohn Marino   else
81e4b17023SJohn Marino     bp_pack_value (bp, 0, 4);
82e4b17023SJohn Marino   bp_pack_value (bp, TREE_ADDRESSABLE (expr), 1);
83e4b17023SJohn Marino   bp_pack_value (bp, TREE_THIS_VOLATILE (expr), 1);
84e4b17023SJohn Marino   if (DECL_P (expr))
85e4b17023SJohn Marino     bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
86e4b17023SJohn Marino   else if (TYPE_P (expr))
87e4b17023SJohn Marino     bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
88e4b17023SJohn Marino   else
89e4b17023SJohn Marino     bp_pack_value (bp, 0, 1);
90e4b17023SJohn Marino   /* We write debug info two times, do not confuse the second one.  */
91e4b17023SJohn Marino   bp_pack_value (bp, ((TYPE_P (expr) || TREE_CODE (expr) == TYPE_DECL)
92e4b17023SJohn Marino 		      ? 0 : TREE_ASM_WRITTEN (expr)), 1);
93e4b17023SJohn Marino   if (TYPE_P (expr))
94e4b17023SJohn Marino     bp_pack_value (bp, TYPE_ARTIFICIAL (expr), 1);
95e4b17023SJohn Marino   else
96e4b17023SJohn Marino     bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
97e4b17023SJohn Marino   bp_pack_value (bp, TREE_USED (expr), 1);
98e4b17023SJohn Marino   bp_pack_value (bp, TREE_NOTHROW (expr), 1);
99e4b17023SJohn Marino   bp_pack_value (bp, TREE_STATIC (expr), 1);
100e4b17023SJohn Marino   bp_pack_value (bp, TREE_PRIVATE (expr), 1);
101e4b17023SJohn Marino   bp_pack_value (bp, TREE_PROTECTED (expr), 1);
102e4b17023SJohn Marino   bp_pack_value (bp, TREE_DEPRECATED (expr), 1);
103e4b17023SJohn Marino   if (TYPE_P (expr))
104e4b17023SJohn Marino     {
105e4b17023SJohn Marino       bp_pack_value (bp, TYPE_SATURATING (expr), 1);
106e4b17023SJohn Marino       bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8);
107e4b17023SJohn Marino     }
108e4b17023SJohn Marino   else if (TREE_CODE (expr) == SSA_NAME)
109e4b17023SJohn Marino     bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
110e4b17023SJohn Marino   else
111e4b17023SJohn Marino     bp_pack_value (bp, 0, 1);
112e4b17023SJohn Marino }
113e4b17023SJohn Marino 
114e4b17023SJohn Marino 
115e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_REAL_CST structure of
116e4b17023SJohn Marino    expression EXPR into bitpack BP.  */
117e4b17023SJohn Marino 
118e4b17023SJohn Marino static void
pack_ts_real_cst_value_fields(struct bitpack_d * bp,tree expr)119e4b17023SJohn Marino pack_ts_real_cst_value_fields (struct bitpack_d *bp, tree expr)
120e4b17023SJohn Marino {
121e4b17023SJohn Marino   unsigned i;
122e4b17023SJohn Marino   REAL_VALUE_TYPE r;
123e4b17023SJohn Marino 
124e4b17023SJohn Marino   r = TREE_REAL_CST (expr);
125e4b17023SJohn Marino   bp_pack_value (bp, r.cl, 2);
126e4b17023SJohn Marino   bp_pack_value (bp, r.decimal, 1);
127e4b17023SJohn Marino   bp_pack_value (bp, r.sign, 1);
128e4b17023SJohn Marino   bp_pack_value (bp, r.signalling, 1);
129e4b17023SJohn Marino   bp_pack_value (bp, r.canonical, 1);
130e4b17023SJohn Marino   bp_pack_value (bp, r.uexp, EXP_BITS);
131e4b17023SJohn Marino   for (i = 0; i < SIGSZ; i++)
132e4b17023SJohn Marino     bp_pack_value (bp, r.sig[i], HOST_BITS_PER_LONG);
133e4b17023SJohn Marino }
134e4b17023SJohn Marino 
135e4b17023SJohn Marino 
136e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_FIXED_CST structure of
137e4b17023SJohn Marino    expression EXPR into bitpack BP.  */
138e4b17023SJohn Marino 
139e4b17023SJohn Marino static void
pack_ts_fixed_cst_value_fields(struct bitpack_d * bp,tree expr)140e4b17023SJohn Marino pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
141e4b17023SJohn Marino {
142e4b17023SJohn Marino   struct fixed_value fv = TREE_FIXED_CST (expr);
143e4b17023SJohn Marino   bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, fv.mode);
144e4b17023SJohn Marino   bp_pack_var_len_int (bp, fv.data.low);
145e4b17023SJohn Marino   bp_pack_var_len_int (bp, fv.data.high);
146e4b17023SJohn Marino }
147e4b17023SJohn Marino 
148e4b17023SJohn Marino 
149e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_DECL_COMMON structure
150e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
151e4b17023SJohn Marino 
152e4b17023SJohn Marino static void
pack_ts_decl_common_value_fields(struct bitpack_d * bp,tree expr)153e4b17023SJohn Marino pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
154e4b17023SJohn Marino {
155e4b17023SJohn Marino   bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr));
156e4b17023SJohn Marino   bp_pack_value (bp, DECL_NONLOCAL (expr), 1);
157e4b17023SJohn Marino   bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1);
158e4b17023SJohn Marino   bp_pack_value (bp, DECL_IGNORED_P (expr), 1);
159e4b17023SJohn Marino   bp_pack_value (bp, DECL_ABSTRACT (expr), 1);
160e4b17023SJohn Marino   bp_pack_value (bp, DECL_ARTIFICIAL (expr), 1);
161e4b17023SJohn Marino   bp_pack_value (bp, DECL_USER_ALIGN (expr), 1);
162e4b17023SJohn Marino   bp_pack_value (bp, DECL_PRESERVE_P (expr), 1);
163e4b17023SJohn Marino   bp_pack_value (bp, DECL_DEBUG_EXPR_IS_FROM (expr), 1);
164e4b17023SJohn Marino   bp_pack_value (bp, DECL_EXTERNAL (expr), 1);
165e4b17023SJohn Marino   bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1);
166e4b17023SJohn Marino   bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr));
167e4b17023SJohn Marino 
168e4b17023SJohn Marino   if (TREE_CODE (expr) == LABEL_DECL)
169e4b17023SJohn Marino     {
170e4b17023SJohn Marino       /* Note that we do not write LABEL_DECL_UID.  The reader will
171e4b17023SJohn Marino 	 always assume an initial value of -1 so that the
172e4b17023SJohn Marino 	 label_to_block_map is recreated by gimple_set_bb.  */
173e4b17023SJohn Marino       bp_pack_value (bp, DECL_ERROR_ISSUED (expr), 1);
174e4b17023SJohn Marino       bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
175e4b17023SJohn Marino     }
176e4b17023SJohn Marino 
177e4b17023SJohn Marino   if (TREE_CODE (expr) == FIELD_DECL)
178e4b17023SJohn Marino     {
179e4b17023SJohn Marino       bp_pack_value (bp, DECL_PACKED (expr), 1);
180e4b17023SJohn Marino       bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1);
181e4b17023SJohn Marino       bp_pack_value (bp, expr->decl_common.off_align, 8);
182e4b17023SJohn Marino     }
183e4b17023SJohn Marino 
184e4b17023SJohn Marino   if (TREE_CODE (expr) == RESULT_DECL
185e4b17023SJohn Marino       || TREE_CODE (expr) == PARM_DECL
186e4b17023SJohn Marino       || TREE_CODE (expr) == VAR_DECL)
187e4b17023SJohn Marino     {
188e4b17023SJohn Marino       bp_pack_value (bp, DECL_BY_REFERENCE (expr), 1);
189e4b17023SJohn Marino       if (TREE_CODE (expr) == VAR_DECL
190e4b17023SJohn Marino 	  || TREE_CODE (expr) == PARM_DECL)
191e4b17023SJohn Marino 	bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1);
192e4b17023SJohn Marino       bp_pack_value (bp, DECL_RESTRICTED_P (expr), 1);
193e4b17023SJohn Marino     }
194e4b17023SJohn Marino }
195e4b17023SJohn Marino 
196e4b17023SJohn Marino 
197e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_DECL_WRTL structure
198e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
199e4b17023SJohn Marino 
200e4b17023SJohn Marino static void
pack_ts_decl_wrtl_value_fields(struct bitpack_d * bp,tree expr)201e4b17023SJohn Marino pack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
202e4b17023SJohn Marino {
203e4b17023SJohn Marino   bp_pack_value (bp, DECL_REGISTER (expr), 1);
204e4b17023SJohn Marino }
205e4b17023SJohn Marino 
206e4b17023SJohn Marino 
207e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_DECL_WITH_VIS structure
208e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
209e4b17023SJohn Marino 
210e4b17023SJohn Marino static void
pack_ts_decl_with_vis_value_fields(struct bitpack_d * bp,tree expr)211e4b17023SJohn Marino pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
212e4b17023SJohn Marino {
213e4b17023SJohn Marino   bp_pack_value (bp, DECL_DEFER_OUTPUT (expr), 1);
214e4b17023SJohn Marino   bp_pack_value (bp, DECL_COMMON (expr), 1);
215e4b17023SJohn Marino   bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1);
216e4b17023SJohn Marino   bp_pack_value (bp, DECL_WEAK (expr), 1);
217e4b17023SJohn Marino   bp_pack_value (bp, DECL_SEEN_IN_BIND_EXPR_P (expr),  1);
218e4b17023SJohn Marino   bp_pack_value (bp, DECL_COMDAT (expr),  1);
219e4b17023SJohn Marino   bp_pack_value (bp, DECL_VISIBILITY (expr),  2);
220e4b17023SJohn Marino   bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr),  1);
221e4b17023SJohn Marino 
222e4b17023SJohn Marino   if (TREE_CODE (expr) == VAR_DECL)
223e4b17023SJohn Marino     {
224e4b17023SJohn Marino       bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
225e4b17023SJohn Marino       bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1);
226e4b17023SJohn Marino       bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
227e4b17023SJohn Marino       bp_pack_value (bp, DECL_TLS_MODEL (expr),  3);
228e4b17023SJohn Marino     }
229e4b17023SJohn Marino 
230e4b17023SJohn Marino   if (VAR_OR_FUNCTION_DECL_P (expr))
231e4b17023SJohn Marino     bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr));
232e4b17023SJohn Marino }
233e4b17023SJohn Marino 
234e4b17023SJohn Marino 
235e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_FUNCTION_DECL structure
236e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
237e4b17023SJohn Marino 
238e4b17023SJohn Marino static void
pack_ts_function_decl_value_fields(struct bitpack_d * bp,tree expr)239e4b17023SJohn Marino pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
240e4b17023SJohn Marino {
241e4b17023SJohn Marino   /* For normal/md builtins we only write the class and code, so they
242e4b17023SJohn Marino      should never be handled here.  */
243e4b17023SJohn Marino   gcc_assert (!streamer_handle_as_builtin_p (expr));
244e4b17023SJohn Marino 
245e4b17023SJohn Marino   bp_pack_enum (bp, built_in_class, BUILT_IN_LAST,
246e4b17023SJohn Marino 		DECL_BUILT_IN_CLASS (expr));
247e4b17023SJohn Marino   bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1);
248e4b17023SJohn Marino   bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1);
249e4b17023SJohn Marino   bp_pack_value (bp, DECL_UNINLINABLE (expr), 1);
250e4b17023SJohn Marino   bp_pack_value (bp, DECL_POSSIBLY_INLINED (expr), 1);
251e4b17023SJohn Marino   bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
252e4b17023SJohn Marino   bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
253e4b17023SJohn Marino   bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
254e4b17023SJohn Marino   bp_pack_value (bp, DECL_IS_OPERATOR_NEW (expr), 1);
255e4b17023SJohn Marino   bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
256e4b17023SJohn Marino   bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
257e4b17023SJohn Marino   bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
258e4b17023SJohn Marino   bp_pack_value (bp, DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr), 1);
259e4b17023SJohn Marino   bp_pack_value (bp, DECL_NO_LIMIT_STACK (expr), 1);
260e4b17023SJohn Marino   bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
261e4b17023SJohn Marino   bp_pack_value (bp, DECL_PURE_P (expr), 1);
262e4b17023SJohn Marino   bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
263e4b17023SJohn Marino   if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
264e4b17023SJohn Marino     bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 11);
265e4b17023SJohn Marino   if (DECL_STATIC_DESTRUCTOR (expr))
266e4b17023SJohn Marino     bp_pack_var_len_unsigned (bp, DECL_FINI_PRIORITY (expr));
267e4b17023SJohn Marino }
268e4b17023SJohn Marino 
269e4b17023SJohn Marino 
270e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_TYPE_COMMON structure
271e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
272e4b17023SJohn Marino 
273e4b17023SJohn Marino static void
pack_ts_type_common_value_fields(struct bitpack_d * bp,tree expr)274e4b17023SJohn Marino pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
275e4b17023SJohn Marino {
276e4b17023SJohn Marino   bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, TYPE_MODE (expr));
277e4b17023SJohn Marino   bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
278e4b17023SJohn Marino   bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
279e4b17023SJohn Marino   bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
280e4b17023SJohn Marino   if (RECORD_OR_UNION_TYPE_P (expr))
281e4b17023SJohn Marino     bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
282*5ce9237cSJohn Marino   else if (TREE_CODE (expr) == ARRAY_TYPE)
283*5ce9237cSJohn Marino     bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
284e4b17023SJohn Marino   bp_pack_value (bp, TYPE_PACKED (expr), 1);
285e4b17023SJohn Marino   bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
286e4b17023SJohn Marino   bp_pack_value (bp, TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2);
287e4b17023SJohn Marino   bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
288e4b17023SJohn Marino   bp_pack_value (bp, TYPE_READONLY (expr), 1);
289e4b17023SJohn Marino   bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
290e4b17023SJohn Marino   bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
291e4b17023SJohn Marino   bp_pack_var_len_int (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1);
292e4b17023SJohn Marino }
293e4b17023SJohn Marino 
294e4b17023SJohn Marino 
295e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_BLOCK structure
296e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
297e4b17023SJohn Marino 
298e4b17023SJohn Marino static void
pack_ts_block_value_fields(struct bitpack_d * bp,tree expr)299e4b17023SJohn Marino pack_ts_block_value_fields (struct bitpack_d *bp, tree expr)
300e4b17023SJohn Marino {
301e4b17023SJohn Marino   bp_pack_value (bp, BLOCK_ABSTRACT (expr), 1);
302e4b17023SJohn Marino   /* BLOCK_NUMBER is recomputed.  */
303e4b17023SJohn Marino }
304e4b17023SJohn Marino 
305e4b17023SJohn Marino /* Pack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL structure
306e4b17023SJohn Marino    of expression EXPR into bitpack BP.  */
307e4b17023SJohn Marino 
308e4b17023SJohn Marino static void
pack_ts_translation_unit_decl_value_fields(struct bitpack_d * bp ATTRIBUTE_UNUSED,tree expr ATTRIBUTE_UNUSED)309e4b17023SJohn Marino pack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
310e4b17023SJohn Marino {
311e4b17023SJohn Marino }
312e4b17023SJohn Marino 
313e4b17023SJohn Marino 
314e4b17023SJohn Marino /* Pack all the bitfields in EXPR into a bit pack.  */
315e4b17023SJohn Marino 
316e4b17023SJohn Marino void
streamer_pack_tree_bitfields(struct bitpack_d * bp,tree expr)317e4b17023SJohn Marino streamer_pack_tree_bitfields (struct bitpack_d *bp, tree expr)
318e4b17023SJohn Marino {
319e4b17023SJohn Marino   enum tree_code code;
320e4b17023SJohn Marino 
321e4b17023SJohn Marino   code = TREE_CODE (expr);
322e4b17023SJohn Marino 
323e4b17023SJohn Marino   /* Note that all these functions are highly sensitive to changes in
324e4b17023SJohn Marino      the types and sizes of each of the fields being packed.  */
325e4b17023SJohn Marino   pack_ts_base_value_fields (bp, expr);
326e4b17023SJohn Marino 
327e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
328e4b17023SJohn Marino     pack_ts_real_cst_value_fields (bp, expr);
329e4b17023SJohn Marino 
330e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
331e4b17023SJohn Marino     pack_ts_fixed_cst_value_fields (bp, expr);
332e4b17023SJohn Marino 
333e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
334e4b17023SJohn Marino     pack_ts_decl_common_value_fields (bp, expr);
335e4b17023SJohn Marino 
336e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
337e4b17023SJohn Marino     pack_ts_decl_wrtl_value_fields (bp, expr);
338e4b17023SJohn Marino 
339e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
340e4b17023SJohn Marino     pack_ts_decl_with_vis_value_fields (bp, expr);
341e4b17023SJohn Marino 
342e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
343e4b17023SJohn Marino     pack_ts_function_decl_value_fields (bp, expr);
344e4b17023SJohn Marino 
345e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
346e4b17023SJohn Marino     pack_ts_type_common_value_fields (bp, expr);
347e4b17023SJohn Marino 
348e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
349e4b17023SJohn Marino     pack_ts_block_value_fields (bp, expr);
350e4b17023SJohn Marino 
351e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
352e4b17023SJohn Marino     pack_ts_translation_unit_decl_value_fields (bp, expr);
353e4b17023SJohn Marino }
354e4b17023SJohn Marino 
355e4b17023SJohn Marino 
356e4b17023SJohn Marino /* Write the code and class of builtin EXPR to output block OB.  IX is
357e4b17023SJohn Marino    the index into the streamer cache where EXPR is stored.*/
358e4b17023SJohn Marino 
359e4b17023SJohn Marino void
streamer_write_builtin(struct output_block * ob,tree expr)360e4b17023SJohn Marino streamer_write_builtin (struct output_block *ob, tree expr)
361e4b17023SJohn Marino {
362e4b17023SJohn Marino   gcc_assert (streamer_handle_as_builtin_p (expr));
363e4b17023SJohn Marino 
364e4b17023SJohn Marino   if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD
365e4b17023SJohn Marino       && !targetm.builtin_decl)
366e4b17023SJohn Marino     sorry ("tree bytecode streams do not support machine specific builtin "
367e4b17023SJohn Marino 	   "functions on this target");
368e4b17023SJohn Marino 
369e4b17023SJohn Marino   streamer_write_record_start (ob, LTO_builtin_decl);
370e4b17023SJohn Marino   streamer_write_enum (ob->main_stream, built_in_class, BUILT_IN_LAST,
371e4b17023SJohn Marino 		       DECL_BUILT_IN_CLASS (expr));
372e4b17023SJohn Marino   streamer_write_uhwi (ob, DECL_FUNCTION_CODE (expr));
373e4b17023SJohn Marino 
374e4b17023SJohn Marino   if (DECL_ASSEMBLER_NAME_SET_P (expr))
375e4b17023SJohn Marino     {
376e4b17023SJohn Marino       /* When the assembler name of a builtin gets a user name,
377e4b17023SJohn Marino 	 the new name is always prefixed with '*' by
378e4b17023SJohn Marino 	 set_builtin_user_assembler_name.  So, to prevent the
379e4b17023SJohn Marino 	 reader side from adding a second '*', we omit it here.  */
380e4b17023SJohn Marino       const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (expr));
381e4b17023SJohn Marino       if (strlen (str) > 1 && str[0] == '*')
382e4b17023SJohn Marino 	streamer_write_string (ob, ob->main_stream, &str[1], true);
383e4b17023SJohn Marino       else
384e4b17023SJohn Marino 	streamer_write_string (ob, ob->main_stream, NULL, true);
385e4b17023SJohn Marino     }
386e4b17023SJohn Marino   else
387e4b17023SJohn Marino     streamer_write_string (ob, ob->main_stream, NULL, true);
388e4b17023SJohn Marino }
389e4b17023SJohn Marino 
390e4b17023SJohn Marino 
391e4b17023SJohn Marino /* Emit the chain of tree nodes starting at T.  OB is the output block
392e4b17023SJohn Marino    to write to.  REF_P is true if chain elements should be emitted
393e4b17023SJohn Marino    as references.  */
394e4b17023SJohn Marino 
395e4b17023SJohn Marino void
streamer_write_chain(struct output_block * ob,tree t,bool ref_p)396e4b17023SJohn Marino streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
397e4b17023SJohn Marino {
398e4b17023SJohn Marino   int i, count;
399e4b17023SJohn Marino 
400e4b17023SJohn Marino   count = list_length (t);
401e4b17023SJohn Marino   streamer_write_hwi (ob, count);
402e4b17023SJohn Marino   for (i = 0; i < count; i++)
403e4b17023SJohn Marino     {
404e4b17023SJohn Marino       tree saved_chain;
405e4b17023SJohn Marino 
406e4b17023SJohn Marino       /* Clear TREE_CHAIN to avoid blindly recursing into the rest
407e4b17023SJohn Marino 	 of the list.  */
408e4b17023SJohn Marino       saved_chain = TREE_CHAIN (t);
409e4b17023SJohn Marino       TREE_CHAIN (t) = NULL_TREE;
410e4b17023SJohn Marino 
411e4b17023SJohn Marino       /* We avoid outputting external vars or functions by reference
412e4b17023SJohn Marino 	 to the global decls section as we do not want to have them
413e4b17023SJohn Marino 	 enter decl merging.  This is, of course, only for the call
414e4b17023SJohn Marino 	 for streaming BLOCK_VARS, but other callers are safe.  */
415e4b17023SJohn Marino       if (VAR_OR_FUNCTION_DECL_P (t)
416e4b17023SJohn Marino 	  && DECL_EXTERNAL (t))
417e4b17023SJohn Marino 	stream_write_tree_shallow_non_ref (ob, t, ref_p);
418e4b17023SJohn Marino       else
419e4b17023SJohn Marino 	stream_write_tree (ob, t, ref_p);
420e4b17023SJohn Marino 
421e4b17023SJohn Marino       TREE_CHAIN (t) = saved_chain;
422e4b17023SJohn Marino       t = TREE_CHAIN (t);
423e4b17023SJohn Marino     }
424e4b17023SJohn Marino }
425e4b17023SJohn Marino 
426e4b17023SJohn Marino 
427e4b17023SJohn Marino /* Write all pointer fields in the TS_COMMON structure of EXPR to output
428e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
429e4b17023SJohn Marino    fields.  */
430e4b17023SJohn Marino 
431e4b17023SJohn Marino static void
write_ts_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)432e4b17023SJohn Marino write_ts_common_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
433e4b17023SJohn Marino {
434e4b17023SJohn Marino   if (TREE_CODE (expr) != IDENTIFIER_NODE)
435e4b17023SJohn Marino     stream_write_tree (ob, TREE_TYPE (expr), ref_p);
436e4b17023SJohn Marino }
437e4b17023SJohn Marino 
438e4b17023SJohn Marino 
439e4b17023SJohn Marino /* Write all pointer fields in the TS_VECTOR structure of EXPR to output
440e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
441e4b17023SJohn Marino    fields.  */
442e4b17023SJohn Marino 
443e4b17023SJohn Marino static void
write_ts_vector_tree_pointers(struct output_block * ob,tree expr,bool ref_p)444e4b17023SJohn Marino write_ts_vector_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
445e4b17023SJohn Marino {
446e4b17023SJohn Marino   streamer_write_chain (ob, TREE_VECTOR_CST_ELTS (expr), ref_p);
447e4b17023SJohn Marino }
448e4b17023SJohn Marino 
449e4b17023SJohn Marino 
450e4b17023SJohn Marino /* Write all pointer fields in the TS_COMPLEX structure of EXPR to output
451e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
452e4b17023SJohn Marino    fields.  */
453e4b17023SJohn Marino 
454e4b17023SJohn Marino static void
write_ts_complex_tree_pointers(struct output_block * ob,tree expr,bool ref_p)455e4b17023SJohn Marino write_ts_complex_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
456e4b17023SJohn Marino {
457e4b17023SJohn Marino   stream_write_tree (ob, TREE_REALPART (expr), ref_p);
458e4b17023SJohn Marino   stream_write_tree (ob, TREE_IMAGPART (expr), ref_p);
459e4b17023SJohn Marino }
460e4b17023SJohn Marino 
461e4b17023SJohn Marino 
462e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_MINIMAL structure of EXPR
463e4b17023SJohn Marino    to output block OB.  If REF_P is true, write a reference to EXPR's
464e4b17023SJohn Marino    pointer fields.  */
465e4b17023SJohn Marino 
466e4b17023SJohn Marino static void
write_ts_decl_minimal_tree_pointers(struct output_block * ob,tree expr,bool ref_p)467e4b17023SJohn Marino write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
468e4b17023SJohn Marino 				     bool ref_p)
469e4b17023SJohn Marino {
470e4b17023SJohn Marino   stream_write_tree (ob, DECL_NAME (expr), ref_p);
471e4b17023SJohn Marino   stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
472e4b17023SJohn Marino   lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
473e4b17023SJohn Marino }
474e4b17023SJohn Marino 
475e4b17023SJohn Marino 
476e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_COMMON structure of EXPR to
477e4b17023SJohn Marino    output block OB.  If REF_P is true, write a reference to EXPR's
478e4b17023SJohn Marino    pointer fields.  */
479e4b17023SJohn Marino 
480e4b17023SJohn Marino static void
write_ts_decl_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)481e4b17023SJohn Marino write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
482e4b17023SJohn Marino 				    bool ref_p)
483e4b17023SJohn Marino {
484e4b17023SJohn Marino   stream_write_tree (ob, DECL_SIZE (expr), ref_p);
485e4b17023SJohn Marino   stream_write_tree (ob, DECL_SIZE_UNIT (expr), ref_p);
486e4b17023SJohn Marino 
487e4b17023SJohn Marino   /* Note, DECL_INITIAL is not handled here.  Since DECL_INITIAL needs
488e4b17023SJohn Marino      special handling in LTO, it must be handled by streamer hooks.  */
489e4b17023SJohn Marino 
490e4b17023SJohn Marino   stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
491e4b17023SJohn Marino 
492e4b17023SJohn Marino   /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
493e4b17023SJohn Marino      for early inlining so drop it on the floor instead of ICEing in
494e4b17023SJohn Marino      dwarf2out.c.  */
495e4b17023SJohn Marino 
496e4b17023SJohn Marino   if (TREE_CODE (expr) == PARM_DECL)
497e4b17023SJohn Marino     streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);
498e4b17023SJohn Marino 
499e4b17023SJohn Marino   if ((TREE_CODE (expr) == VAR_DECL
500e4b17023SJohn Marino        || TREE_CODE (expr) == PARM_DECL)
501e4b17023SJohn Marino       && DECL_HAS_VALUE_EXPR_P (expr))
502e4b17023SJohn Marino     stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);
503e4b17023SJohn Marino 
504e4b17023SJohn Marino   if (TREE_CODE (expr) == VAR_DECL)
505e4b17023SJohn Marino     stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
506e4b17023SJohn Marino }
507e4b17023SJohn Marino 
508e4b17023SJohn Marino 
509e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_NON_COMMON structure of
510e4b17023SJohn Marino    EXPR to output block OB.  If REF_P is true, write a reference to EXPR's
511e4b17023SJohn Marino    pointer fields.  */
512e4b17023SJohn Marino 
513e4b17023SJohn Marino static void
write_ts_decl_non_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)514e4b17023SJohn Marino write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
515e4b17023SJohn Marino 				        bool ref_p)
516e4b17023SJohn Marino {
517e4b17023SJohn Marino   if (TREE_CODE (expr) == FUNCTION_DECL)
518e4b17023SJohn Marino     {
519e4b17023SJohn Marino       stream_write_tree (ob, DECL_ARGUMENTS (expr), ref_p);
520e4b17023SJohn Marino       stream_write_tree (ob, DECL_RESULT (expr), ref_p);
521e4b17023SJohn Marino     }
522e4b17023SJohn Marino   else if (TREE_CODE (expr) == TYPE_DECL)
523e4b17023SJohn Marino     stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
524e4b17023SJohn Marino   stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
525e4b17023SJohn Marino }
526e4b17023SJohn Marino 
527e4b17023SJohn Marino 
528e4b17023SJohn Marino /* Write all pointer fields in the TS_DECL_WITH_VIS structure of EXPR
529e4b17023SJohn Marino    to output block OB.  If REF_P is true, write a reference to EXPR's
530e4b17023SJohn Marino    pointer fields.  */
531e4b17023SJohn Marino 
532e4b17023SJohn Marino static void
write_ts_decl_with_vis_tree_pointers(struct output_block * ob,tree expr,bool ref_p)533e4b17023SJohn Marino write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
534e4b17023SJohn Marino 			              bool ref_p)
535e4b17023SJohn Marino {
536e4b17023SJohn Marino   /* Make sure we don't inadvertently set the assembler name.  */
537e4b17023SJohn Marino   if (DECL_ASSEMBLER_NAME_SET_P (expr))
538e4b17023SJohn Marino     stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
539e4b17023SJohn Marino   else
540e4b17023SJohn Marino     stream_write_tree (ob, NULL_TREE, false);
541e4b17023SJohn Marino 
542e4b17023SJohn Marino   stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
543e4b17023SJohn Marino   stream_write_tree (ob, DECL_COMDAT_GROUP (expr), ref_p);
544e4b17023SJohn Marino }
545e4b17023SJohn Marino 
546e4b17023SJohn Marino 
547e4b17023SJohn Marino /* Write all pointer fields in the TS_FIELD_DECL structure of EXPR to
548e4b17023SJohn Marino    output block OB.  If REF_P is true, write a reference to EXPR's
549e4b17023SJohn Marino    pointer fields.  */
550e4b17023SJohn Marino 
551e4b17023SJohn Marino static void
write_ts_field_decl_tree_pointers(struct output_block * ob,tree expr,bool ref_p)552e4b17023SJohn Marino write_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
553e4b17023SJohn Marino 				   bool ref_p)
554e4b17023SJohn Marino {
555e4b17023SJohn Marino   stream_write_tree (ob, DECL_FIELD_OFFSET (expr), ref_p);
556e4b17023SJohn Marino   stream_write_tree (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
557e4b17023SJohn Marino   stream_write_tree (ob, DECL_BIT_FIELD_REPRESENTATIVE (expr), ref_p);
558e4b17023SJohn Marino   stream_write_tree (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
559e4b17023SJohn Marino   stream_write_tree (ob, DECL_FCONTEXT (expr), ref_p);
560e4b17023SJohn Marino }
561e4b17023SJohn Marino 
562e4b17023SJohn Marino 
563e4b17023SJohn Marino /* Write all pointer fields in the TS_FUNCTION_DECL structure of EXPR
564e4b17023SJohn Marino    to output block OB.  If REF_P is true, write a reference to EXPR's
565e4b17023SJohn Marino    pointer fields.  */
566e4b17023SJohn Marino 
567e4b17023SJohn Marino static void
write_ts_function_decl_tree_pointers(struct output_block * ob,tree expr,bool ref_p)568e4b17023SJohn Marino write_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
569e4b17023SJohn Marino 				      bool ref_p)
570e4b17023SJohn Marino {
571e4b17023SJohn Marino   /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  FIXME lto,
572e4b17023SJohn Marino      maybe it should be handled here?  */
573e4b17023SJohn Marino   stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
574e4b17023SJohn Marino   stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
575e4b17023SJohn Marino   stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
576e4b17023SJohn Marino }
577e4b17023SJohn Marino 
578e4b17023SJohn Marino 
579e4b17023SJohn Marino /* Write all pointer fields in the TS_TYPE_COMMON structure of EXPR to
580e4b17023SJohn Marino    output block OB.  If REF_P is true, write a reference to EXPR's
581e4b17023SJohn Marino    pointer fields.  */
582e4b17023SJohn Marino 
583e4b17023SJohn Marino static void
write_ts_type_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)584e4b17023SJohn Marino write_ts_type_common_tree_pointers (struct output_block *ob, tree expr,
585e4b17023SJohn Marino 				    bool ref_p)
586e4b17023SJohn Marino {
587e4b17023SJohn Marino   stream_write_tree (ob, TYPE_SIZE (expr), ref_p);
588e4b17023SJohn Marino   stream_write_tree (ob, TYPE_SIZE_UNIT (expr), ref_p);
589e4b17023SJohn Marino   stream_write_tree (ob, TYPE_ATTRIBUTES (expr), ref_p);
590e4b17023SJohn Marino   stream_write_tree (ob, TYPE_NAME (expr), ref_p);
591e4b17023SJohn Marino   /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO.  They will be
592e4b17023SJohn Marino      reconstructed during fixup.  */
593e4b17023SJohn Marino   /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
594e4b17023SJohn Marino      during fixup.  */
595e4b17023SJohn Marino   stream_write_tree (ob, TYPE_MAIN_VARIANT (expr), ref_p);
596e4b17023SJohn Marino   stream_write_tree (ob, TYPE_CONTEXT (expr), ref_p);
597e4b17023SJohn Marino   /* TYPE_CANONICAL is re-computed during type merging, so no need
598e4b17023SJohn Marino      to stream it here.  */
599e4b17023SJohn Marino   stream_write_tree (ob, TYPE_STUB_DECL (expr), ref_p);
600e4b17023SJohn Marino }
601e4b17023SJohn Marino 
602e4b17023SJohn Marino /* Write all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
603e4b17023SJohn Marino    to output block OB.  If REF_P is true, write a reference to EXPR's
604e4b17023SJohn Marino    pointer fields.  */
605e4b17023SJohn Marino 
606e4b17023SJohn Marino static void
write_ts_type_non_common_tree_pointers(struct output_block * ob,tree expr,bool ref_p)607e4b17023SJohn Marino write_ts_type_non_common_tree_pointers (struct output_block *ob, tree expr,
608e4b17023SJohn Marino 					bool ref_p)
609e4b17023SJohn Marino {
610e4b17023SJohn Marino   if (TREE_CODE (expr) == ENUMERAL_TYPE)
611e4b17023SJohn Marino     stream_write_tree (ob, TYPE_VALUES (expr), ref_p);
612e4b17023SJohn Marino   else if (TREE_CODE (expr) == ARRAY_TYPE)
613e4b17023SJohn Marino     stream_write_tree (ob, TYPE_DOMAIN (expr), ref_p);
614e4b17023SJohn Marino   else if (RECORD_OR_UNION_TYPE_P (expr))
615e4b17023SJohn Marino     streamer_write_chain (ob, TYPE_FIELDS (expr), ref_p);
616e4b17023SJohn Marino   else if (TREE_CODE (expr) == FUNCTION_TYPE
617e4b17023SJohn Marino 	   || TREE_CODE (expr) == METHOD_TYPE)
618e4b17023SJohn Marino     stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);
619e4b17023SJohn Marino 
620e4b17023SJohn Marino   if (!POINTER_TYPE_P (expr))
621e4b17023SJohn Marino     stream_write_tree (ob, TYPE_MINVAL (expr), ref_p);
622e4b17023SJohn Marino   stream_write_tree (ob, TYPE_MAXVAL (expr), ref_p);
623e4b17023SJohn Marino   if (RECORD_OR_UNION_TYPE_P (expr))
624e4b17023SJohn Marino     stream_write_tree (ob, TYPE_BINFO (expr), ref_p);
625e4b17023SJohn Marino }
626e4b17023SJohn Marino 
627e4b17023SJohn Marino 
628e4b17023SJohn Marino /* Write all pointer fields in the TS_LIST structure of EXPR to output
629e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
630e4b17023SJohn Marino    fields.  */
631e4b17023SJohn Marino 
632e4b17023SJohn Marino static void
write_ts_list_tree_pointers(struct output_block * ob,tree expr,bool ref_p)633e4b17023SJohn Marino write_ts_list_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
634e4b17023SJohn Marino {
635e4b17023SJohn Marino   stream_write_tree (ob, TREE_PURPOSE (expr), ref_p);
636e4b17023SJohn Marino   stream_write_tree (ob, TREE_VALUE (expr), ref_p);
637e4b17023SJohn Marino   streamer_write_chain (ob, TREE_CHAIN (expr), ref_p);
638e4b17023SJohn Marino }
639e4b17023SJohn Marino 
640e4b17023SJohn Marino 
641e4b17023SJohn Marino /* Write all pointer fields in the TS_VEC structure of EXPR to output
642e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
643e4b17023SJohn Marino    fields.  */
644e4b17023SJohn Marino 
645e4b17023SJohn Marino static void
write_ts_vec_tree_pointers(struct output_block * ob,tree expr,bool ref_p)646e4b17023SJohn Marino write_ts_vec_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
647e4b17023SJohn Marino {
648e4b17023SJohn Marino   int i;
649e4b17023SJohn Marino 
650e4b17023SJohn Marino   /* Note that the number of slots for EXPR has already been emitted
651e4b17023SJohn Marino      in EXPR's header (see streamer_write_tree_header).  */
652e4b17023SJohn Marino   for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
653e4b17023SJohn Marino     stream_write_tree (ob, TREE_VEC_ELT (expr, i), ref_p);
654e4b17023SJohn Marino }
655e4b17023SJohn Marino 
656e4b17023SJohn Marino 
657e4b17023SJohn Marino /* Write all pointer fields in the TS_EXP structure of EXPR to output
658e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
659e4b17023SJohn Marino    fields.  */
660e4b17023SJohn Marino 
661e4b17023SJohn Marino static void
write_ts_exp_tree_pointers(struct output_block * ob,tree expr,bool ref_p)662e4b17023SJohn Marino write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
663e4b17023SJohn Marino {
664e4b17023SJohn Marino   int i;
665e4b17023SJohn Marino 
666e4b17023SJohn Marino   streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
667e4b17023SJohn Marino   for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
668e4b17023SJohn Marino     stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
669e4b17023SJohn Marino   lto_output_location (ob, EXPR_LOCATION (expr));
670e4b17023SJohn Marino   stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
671e4b17023SJohn Marino }
672e4b17023SJohn Marino 
673e4b17023SJohn Marino 
674e4b17023SJohn Marino /* Write all pointer fields in the TS_BLOCK structure of EXPR to output
675e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
676e4b17023SJohn Marino    fields.  */
677e4b17023SJohn Marino 
678e4b17023SJohn Marino static void
write_ts_block_tree_pointers(struct output_block * ob,tree expr,bool ref_p)679e4b17023SJohn Marino write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
680e4b17023SJohn Marino {
681e4b17023SJohn Marino   /* Do not stream BLOCK_SOURCE_LOCATION.  We cannot handle debug information
682e4b17023SJohn Marino      for early inlining so drop it on the floor instead of ICEing in
683e4b17023SJohn Marino      dwarf2out.c.  */
684e4b17023SJohn Marino   streamer_write_chain (ob, BLOCK_VARS (expr), ref_p);
685e4b17023SJohn Marino 
686e4b17023SJohn Marino   /* Do not stream BLOCK_NONLOCALIZED_VARS.  We cannot handle debug information
687e4b17023SJohn Marino      for early inlining so drop it on the floor instead of ICEing in
688e4b17023SJohn Marino      dwarf2out.c.  */
689e4b17023SJohn Marino 
690e4b17023SJohn Marino   stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
691e4b17023SJohn Marino   /* Do not stream BLOCK_ABSTRACT_ORIGIN.  We cannot handle debug information
692e4b17023SJohn Marino      for early inlining so drop it on the floor instead of ICEing in
693e4b17023SJohn Marino      dwarf2out.c.  */
694e4b17023SJohn Marino   stream_write_tree (ob, BLOCK_FRAGMENT_ORIGIN (expr), ref_p);
695e4b17023SJohn Marino   stream_write_tree (ob, BLOCK_FRAGMENT_CHAIN (expr), ref_p);
696e4b17023SJohn Marino   /* Do not output BLOCK_SUBBLOCKS.  Instead on streaming-in this
697e4b17023SJohn Marino      list is re-constructed from BLOCK_SUPERCONTEXT.  */
698e4b17023SJohn Marino }
699e4b17023SJohn Marino 
700e4b17023SJohn Marino 
701e4b17023SJohn Marino /* Write all pointer fields in the TS_BINFO structure of EXPR to output
702e4b17023SJohn Marino    block OB.  If REF_P is true, write a reference to EXPR's pointer
703e4b17023SJohn Marino    fields.  */
704e4b17023SJohn Marino 
705e4b17023SJohn Marino static void
write_ts_binfo_tree_pointers(struct output_block * ob,tree expr,bool ref_p)706e4b17023SJohn Marino write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
707e4b17023SJohn Marino {
708e4b17023SJohn Marino   unsigned i;
709e4b17023SJohn Marino   tree t;
710e4b17023SJohn Marino 
711e4b17023SJohn Marino   /* Note that the number of BINFO slots has already been emitted in
712e4b17023SJohn Marino      EXPR's header (see streamer_write_tree_header) because this length
713e4b17023SJohn Marino      is needed to build the empty BINFO node on the reader side.  */
714e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (expr), i, t)
715e4b17023SJohn Marino     stream_write_tree (ob, t, ref_p);
716e4b17023SJohn Marino   stream_write_tree (ob, NULL_TREE, false);
717e4b17023SJohn Marino 
718e4b17023SJohn Marino   stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
719e4b17023SJohn Marino   stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
720e4b17023SJohn Marino   stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
721e4b17023SJohn Marino 
722e4b17023SJohn Marino   streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
723e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t)
724e4b17023SJohn Marino     stream_write_tree (ob, t, ref_p);
725e4b17023SJohn Marino 
726e4b17023SJohn Marino   stream_write_tree (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
727e4b17023SJohn Marino   stream_write_tree (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
728e4b17023SJohn Marino   stream_write_tree (ob, BINFO_VPTR_INDEX (expr), ref_p);
729e4b17023SJohn Marino }
730e4b17023SJohn Marino 
731e4b17023SJohn Marino 
732e4b17023SJohn Marino /* Write all pointer fields in the TS_CONSTRUCTOR structure of EXPR to
733e4b17023SJohn Marino    output block OB.  If REF_P is true, write a reference to EXPR's
734e4b17023SJohn Marino    pointer fields.  */
735e4b17023SJohn Marino 
736e4b17023SJohn Marino static void
write_ts_constructor_tree_pointers(struct output_block * ob,tree expr,bool ref_p)737e4b17023SJohn Marino write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
738e4b17023SJohn Marino 				    bool ref_p)
739e4b17023SJohn Marino {
740e4b17023SJohn Marino   unsigned i;
741e4b17023SJohn Marino   tree index, value;
742e4b17023SJohn Marino 
743e4b17023SJohn Marino   streamer_write_uhwi (ob, CONSTRUCTOR_NELTS (expr));
744e4b17023SJohn Marino   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
745e4b17023SJohn Marino     {
746e4b17023SJohn Marino       stream_write_tree (ob, index, ref_p);
747e4b17023SJohn Marino       stream_write_tree (ob, value, ref_p);
748e4b17023SJohn Marino     }
749e4b17023SJohn Marino }
750e4b17023SJohn Marino 
751e4b17023SJohn Marino /* Write a TS_TARGET_OPTION tree in EXPR to OB.  */
752e4b17023SJohn Marino 
753e4b17023SJohn Marino static void
write_ts_target_option(struct output_block * ob,tree expr)754e4b17023SJohn Marino write_ts_target_option (struct output_block *ob, tree expr)
755e4b17023SJohn Marino {
756e4b17023SJohn Marino   struct cl_target_option *t = TREE_TARGET_OPTION (expr);
757e4b17023SJohn Marino   struct bitpack_d bp;
758e4b17023SJohn Marino   unsigned i, len;
759e4b17023SJohn Marino 
760e4b17023SJohn Marino   /* The cl_target_option is target specific and generated by the options
761e4b17023SJohn Marino      awk script, so we just recreate a byte-by-byte copy here. */
762e4b17023SJohn Marino 
763e4b17023SJohn Marino   bp = bitpack_create (ob->main_stream);
764e4b17023SJohn Marino   len = sizeof (struct cl_target_option);
765e4b17023SJohn Marino   for (i = 0; i < len; i++)
766e4b17023SJohn Marino     bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
767e4b17023SJohn Marino   /* Catch struct size mismatches between reader and writer. */
768e4b17023SJohn Marino   bp_pack_value (&bp, 0x12345678, 32);
769e4b17023SJohn Marino   streamer_write_bitpack (&bp);
770e4b17023SJohn Marino }
771e4b17023SJohn Marino 
772e4b17023SJohn Marino /* Write a TS_OPTIMIZATION tree in EXPR to OB.  */
773e4b17023SJohn Marino 
774e4b17023SJohn Marino static void
write_ts_optimization(struct output_block * ob,tree expr)775e4b17023SJohn Marino write_ts_optimization (struct output_block *ob, tree expr)
776e4b17023SJohn Marino {
777e4b17023SJohn Marino   struct cl_optimization *t = TREE_OPTIMIZATION (expr);
778e4b17023SJohn Marino   struct bitpack_d bp;
779e4b17023SJohn Marino   unsigned i, len;
780e4b17023SJohn Marino 
781e4b17023SJohn Marino   /* The cl_optimization is generated by the options
782e4b17023SJohn Marino      awk script, so we just recreate a byte-by-byte copy here. */
783e4b17023SJohn Marino 
784e4b17023SJohn Marino   bp = bitpack_create (ob->main_stream);
785e4b17023SJohn Marino   len = sizeof (struct cl_optimization);
786e4b17023SJohn Marino   for (i = 0; i < len; i++)
787e4b17023SJohn Marino     bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
788e4b17023SJohn Marino   /* Catch struct size mismatches between reader and writer. */
789e4b17023SJohn Marino   bp_pack_value (&bp, 0x12345678, 32);
790e4b17023SJohn Marino   streamer_write_bitpack (&bp);
791e4b17023SJohn Marino }
792e4b17023SJohn Marino 
793e4b17023SJohn Marino /* Write a TS_TRANSLATION_UNIT_DECL tree in EXPR to OB.  */
794e4b17023SJohn Marino 
795e4b17023SJohn Marino static void
write_ts_translation_unit_decl_tree_pointers(struct output_block * ob,tree expr)796e4b17023SJohn Marino write_ts_translation_unit_decl_tree_pointers (struct output_block *ob,
797e4b17023SJohn Marino 					      tree expr)
798e4b17023SJohn Marino {
799e4b17023SJohn Marino   streamer_write_string (ob, ob->main_stream,
800e4b17023SJohn Marino 			 TRANSLATION_UNIT_LANGUAGE (expr), true);
801e4b17023SJohn Marino }
802e4b17023SJohn Marino 
803e4b17023SJohn Marino /* Write all pointer fields in EXPR to output block OB.  If REF_P is true,
804e4b17023SJohn Marino    the leaves of EXPR are emitted as references.  */
805e4b17023SJohn Marino 
806e4b17023SJohn Marino void
streamer_write_tree_body(struct output_block * ob,tree expr,bool ref_p)807e4b17023SJohn Marino streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
808e4b17023SJohn Marino {
809e4b17023SJohn Marino   enum tree_code code;
810e4b17023SJohn Marino 
811e4b17023SJohn Marino   code = TREE_CODE (expr);
812e4b17023SJohn Marino 
813e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
814e4b17023SJohn Marino     write_ts_common_tree_pointers (ob, expr, ref_p);
815e4b17023SJohn Marino 
816e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
817e4b17023SJohn Marino     write_ts_vector_tree_pointers (ob, expr, ref_p);
818e4b17023SJohn Marino 
819e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
820e4b17023SJohn Marino     write_ts_complex_tree_pointers (ob, expr, ref_p);
821e4b17023SJohn Marino 
822e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
823e4b17023SJohn Marino     write_ts_decl_minimal_tree_pointers (ob, expr, ref_p);
824e4b17023SJohn Marino 
825e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
826e4b17023SJohn Marino     write_ts_decl_common_tree_pointers (ob, expr, ref_p);
827e4b17023SJohn Marino 
828e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
829e4b17023SJohn Marino     write_ts_decl_non_common_tree_pointers (ob, expr, ref_p);
830e4b17023SJohn Marino 
831e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
832e4b17023SJohn Marino     write_ts_decl_with_vis_tree_pointers (ob, expr, ref_p);
833e4b17023SJohn Marino 
834e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
835e4b17023SJohn Marino     write_ts_field_decl_tree_pointers (ob, expr, ref_p);
836e4b17023SJohn Marino 
837e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
838e4b17023SJohn Marino     write_ts_function_decl_tree_pointers (ob, expr, ref_p);
839e4b17023SJohn Marino 
840e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
841e4b17023SJohn Marino     write_ts_type_common_tree_pointers (ob, expr, ref_p);
842e4b17023SJohn Marino 
843e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
844e4b17023SJohn Marino     write_ts_type_non_common_tree_pointers (ob, expr, ref_p);
845e4b17023SJohn Marino 
846e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_LIST))
847e4b17023SJohn Marino     write_ts_list_tree_pointers (ob, expr, ref_p);
848e4b17023SJohn Marino 
849e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_VEC))
850e4b17023SJohn Marino     write_ts_vec_tree_pointers (ob, expr, ref_p);
851e4b17023SJohn Marino 
852e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_EXP))
853e4b17023SJohn Marino     write_ts_exp_tree_pointers (ob, expr, ref_p);
854e4b17023SJohn Marino 
855e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
856e4b17023SJohn Marino     write_ts_block_tree_pointers (ob, expr, ref_p);
857e4b17023SJohn Marino 
858e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
859e4b17023SJohn Marino     write_ts_binfo_tree_pointers (ob, expr, ref_p);
860e4b17023SJohn Marino 
861e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
862e4b17023SJohn Marino     write_ts_constructor_tree_pointers (ob, expr, ref_p);
863e4b17023SJohn Marino 
864e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
865e4b17023SJohn Marino     write_ts_target_option (ob, expr);
866e4b17023SJohn Marino 
867e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
868e4b17023SJohn Marino     write_ts_optimization (ob, expr);
869e4b17023SJohn Marino 
870e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
871e4b17023SJohn Marino     write_ts_translation_unit_decl_tree_pointers (ob, expr);
872e4b17023SJohn Marino }
873e4b17023SJohn Marino 
874e4b17023SJohn Marino 
875e4b17023SJohn Marino /* Emit header information for tree EXPR to output block OB.  The header
876e4b17023SJohn Marino    contains everything needed to instantiate an empty skeleton for
877e4b17023SJohn Marino    EXPR on the reading side.  IX is the index into the streamer cache
878e4b17023SJohn Marino    where EXPR is stored.  */
879e4b17023SJohn Marino 
880e4b17023SJohn Marino void
streamer_write_tree_header(struct output_block * ob,tree expr)881e4b17023SJohn Marino streamer_write_tree_header (struct output_block *ob, tree expr)
882e4b17023SJohn Marino {
883e4b17023SJohn Marino   enum LTO_tags tag;
884e4b17023SJohn Marino   enum tree_code code;
885e4b17023SJohn Marino 
886e4b17023SJohn Marino   /* We should not see any tree nodes not handled by the streamer.  */
887e4b17023SJohn Marino   code = TREE_CODE (expr);
888e4b17023SJohn Marino 
889e4b17023SJohn Marino   /* The header of a tree node consists of its tag, the size of
890e4b17023SJohn Marino      the node, and any other information needed to instantiate
891e4b17023SJohn Marino      EXPR on the reading side (such as the number of slots in
892e4b17023SJohn Marino      variable sized nodes).  */
893e4b17023SJohn Marino   tag = lto_tree_code_to_tag (code);
894e4b17023SJohn Marino   streamer_write_record_start (ob, tag);
895e4b17023SJohn Marino 
896e4b17023SJohn Marino   /* The following will cause bootstrap miscomparisons.  Enable with care.  */
897e4b17023SJohn Marino #ifdef LTO_STREAMER_DEBUG
898e4b17023SJohn Marino   /* This is used mainly for debugging purposes.  When the reader
899e4b17023SJohn Marino      and the writer do not agree on a streamed node, the pointer
900e4b17023SJohn Marino      value for EXPR can be used to track down the differences in
901e4b17023SJohn Marino      the debugger.  */
902e4b17023SJohn Marino   gcc_assert ((HOST_WIDEST_INT) (intptr_t) expr == (intptr_t) expr);
903e4b17023SJohn Marino   streamer_write_hwi (ob, (HOST_WIDEST_INT) (intptr_t) expr);
904e4b17023SJohn Marino #endif
905e4b17023SJohn Marino 
906e4b17023SJohn Marino   /* The text in strings and identifiers are completely emitted in
907e4b17023SJohn Marino      the header.  */
908e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_STRING))
909e4b17023SJohn Marino     streamer_write_string_cst (ob, ob->main_stream, expr);
910e4b17023SJohn Marino   else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
911e4b17023SJohn Marino     write_identifier (ob, ob->main_stream, expr);
912e4b17023SJohn Marino   else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
913e4b17023SJohn Marino     streamer_write_hwi (ob, TREE_VEC_LENGTH (expr));
914e4b17023SJohn Marino   else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
915e4b17023SJohn Marino     streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
916e4b17023SJohn Marino   else if (TREE_CODE (expr) == CALL_EXPR)
917e4b17023SJohn Marino     streamer_write_uhwi (ob, call_expr_nargs (expr));
918e4b17023SJohn Marino }
919e4b17023SJohn Marino 
920e4b17023SJohn Marino 
921e4b17023SJohn Marino /* Emit the integer constant CST to output block OB.  If REF_P is true,
922e4b17023SJohn Marino    CST's type will be emitted as a reference.  */
923e4b17023SJohn Marino 
924e4b17023SJohn Marino void
streamer_write_integer_cst(struct output_block * ob,tree cst,bool ref_p)925e4b17023SJohn Marino streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p)
926e4b17023SJohn Marino {
927e4b17023SJohn Marino   streamer_write_record_start (ob, lto_tree_code_to_tag (INTEGER_CST));
928e4b17023SJohn Marino   stream_write_tree (ob, TREE_TYPE (cst), ref_p);
929e4b17023SJohn Marino   streamer_write_char_stream (ob->main_stream, TREE_OVERFLOW_P (cst));
930e4b17023SJohn Marino   streamer_write_uhwi (ob, TREE_INT_CST_LOW (cst));
931e4b17023SJohn Marino   streamer_write_uhwi (ob, TREE_INT_CST_HIGH (cst));
932e4b17023SJohn Marino }
933