File: | build/gcc/lto-streamer-in.cc |
Warning: | line 1635, column 33 The right operand of '+' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Read the GIMPLE representation from a file stream. | |||
2 | ||||
3 | Copyright (C) 2009-2023 Free Software Foundation, Inc. | |||
4 | Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> | |||
5 | Re-implemented by Diego Novillo <dnovillo@google.com> | |||
6 | ||||
7 | This file is part of GCC. | |||
8 | ||||
9 | GCC is free software; you can redistribute it and/or modify it under | |||
10 | the terms of the GNU General Public License as published by the Free | |||
11 | Software Foundation; either version 3, or (at your option) any later | |||
12 | version. | |||
13 | ||||
14 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |||
15 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
17 | for more details. | |||
18 | ||||
19 | You should have received a copy of the GNU General Public License | |||
20 | along with GCC; see the file COPYING3. If not see | |||
21 | <http://www.gnu.org/licenses/>. */ | |||
22 | ||||
23 | #include "config.h" | |||
24 | #include "system.h" | |||
25 | #include "coretypes.h" | |||
26 | #include "backend.h" | |||
27 | #include "target.h" | |||
28 | #include "rtl.h" | |||
29 | #include "tree.h" | |||
30 | #include "gimple.h" | |||
31 | #include "cfghooks.h" | |||
32 | #include "tree-pass.h" | |||
33 | #include "ssa.h" | |||
34 | #include "gimple-streamer.h" | |||
35 | #include "toplev.h" | |||
36 | #include "gimple-iterator.h" | |||
37 | #include "tree-cfg.h" | |||
38 | #include "tree-into-ssa.h" | |||
39 | #include "tree-dfa.h" | |||
40 | #include "tree-ssa.h" | |||
41 | #include "except.h" | |||
42 | #include "cgraph.h" | |||
43 | #include "cfgloop.h" | |||
44 | #include "debug.h" | |||
45 | #include "alloc-pool.h" | |||
46 | #include "toplev.h" | |||
47 | ||||
48 | /* Allocator used to hold string slot entries for line map streaming. */ | |||
49 | static struct object_allocator<struct string_slot> *string_slot_allocator; | |||
50 | ||||
51 | /* The table to hold the file names. */ | |||
52 | static hash_table<string_slot_hasher> *file_name_hash_table; | |||
53 | ||||
54 | /* The table to hold the relative pathname prefixes. */ | |||
55 | ||||
56 | /* This obstack holds file names used in locators. Line map datastructures | |||
57 | points here and thus it needs to be kept allocated as long as linemaps | |||
58 | exists. */ | |||
59 | static struct obstack file_name_obstack; | |||
60 | ||||
61 | /* Map a pair of nul terminated strings where the first one can be | |||
62 | pointer compared, but the second can't, to another string. */ | |||
63 | struct string_pair_map | |||
64 | { | |||
65 | const char *str1; | |||
66 | const char *str2; | |||
67 | const char *str3; | |||
68 | hashval_t hash; | |||
69 | bool prefix; | |||
70 | }; | |||
71 | ||||
72 | /* Allocator used to hold string pair map entries for line map streaming. */ | |||
73 | static struct object_allocator<struct string_pair_map> | |||
74 | *string_pair_map_allocator; | |||
75 | ||||
76 | struct string_pair_map_hasher : nofree_ptr_hash <string_pair_map> | |||
77 | { | |||
78 | static inline hashval_t hash (const string_pair_map *); | |||
79 | static inline bool equal (const string_pair_map *, const string_pair_map *); | |||
80 | }; | |||
81 | ||||
82 | inline hashval_t | |||
83 | string_pair_map_hasher::hash (const string_pair_map *spm) | |||
84 | { | |||
85 | return spm->hash; | |||
86 | } | |||
87 | ||||
88 | inline bool | |||
89 | string_pair_map_hasher::equal (const string_pair_map *spm1, | |||
90 | const string_pair_map *spm2) | |||
91 | { | |||
92 | return (spm1->hash == spm2->hash | |||
93 | && spm1->str1 == spm2->str1 | |||
94 | && spm1->prefix == spm2->prefix | |||
95 | && strcmp (spm1->str2, spm2->str2) == 0); | |||
96 | } | |||
97 | ||||
98 | /* The table to hold the pairs of pathnames and corresponding | |||
99 | resulting pathname. Used for both mapping of get_src_pwd () | |||
100 | and recorded source working directory to relative path prefix | |||
101 | from current working directory to the recorded one, and for | |||
102 | mapping of that relative path prefix and some relative path | |||
103 | to those concatenated. */ | |||
104 | static hash_table<string_pair_map_hasher> *path_name_pair_hash_table; | |||
105 | ||||
106 | ||||
107 | /* Check that tag ACTUAL has one of the given values. NUM_TAGS is the | |||
108 | number of valid tag values to check. */ | |||
109 | ||||
110 | void | |||
111 | lto_tag_check_set (enum LTO_tags actual, int ntags, ...) | |||
112 | { | |||
113 | va_list ap; | |||
114 | int i; | |||
115 | ||||
116 | va_start (ap, ntags)__builtin_va_start(ap, ntags); | |||
117 | for (i = 0; i < ntags; i++) | |||
118 | if ((unsigned) actual == va_arg (ap, unsigned)__builtin_va_arg(ap, unsigned)) | |||
119 | { | |||
120 | va_end (ap)__builtin_va_end(ap); | |||
121 | return; | |||
122 | } | |||
123 | ||||
124 | va_end (ap)__builtin_va_end(ap); | |||
125 | internal_error ("bytecode stream: unexpected tag %s", lto_tag_name (actual)); | |||
126 | } | |||
127 | ||||
128 | ||||
129 | /* Read LENGTH bytes from STREAM to ADDR. */ | |||
130 | ||||
131 | void | |||
132 | lto_input_data_block (class lto_input_block *ib, void *addr, size_t length) | |||
133 | { | |||
134 | size_t i; | |||
135 | unsigned char *const buffer = (unsigned char *) addr; | |||
136 | ||||
137 | for (i = 0; i < length; i++) | |||
138 | buffer[i] = streamer_read_uchar (ib); | |||
139 | } | |||
140 | ||||
141 | /* Compute the relative path to get to DATA_WD (absolute directory name) | |||
142 | from CWD (another absolute directory name). E.g. for | |||
143 | DATA_WD of "/tmp/foo/bar" and CWD of "/tmp/baz/qux" return | |||
144 | "../../foo/bar". Returned string should be freed by the caller. | |||
145 | Return NULL if absolute file name needs to be used. */ | |||
146 | ||||
147 | static char * | |||
148 | relative_path_prefix (const char *data_wd, const char *cwd) | |||
149 | { | |||
150 | const char *d = data_wd; | |||
151 | const char *c = cwd; | |||
152 | #ifdef HAVE_DOS_BASED_FILE_SYSTEM | |||
153 | if (d[1] == ':') | |||
154 | { | |||
155 | if (!IS_DIR_SEPARATOR (d[2])(((d[2]) == '/') || (((d[2]) == '\\') && (0)))) | |||
156 | return NULLnullptr; | |||
157 | if (c[0] == d[0] && c[1] == ':' && IS_DIR_SEPARATOR (c[2])(((c[2]) == '/') || (((c[2]) == '\\') && (0)))) | |||
158 | { | |||
159 | c += 3; | |||
160 | d += 3; | |||
161 | } | |||
162 | else | |||
163 | return NULLnullptr; | |||
164 | } | |||
165 | else if (c[1] == ':') | |||
166 | return NULLnullptr; | |||
167 | #endif | |||
168 | do | |||
169 | { | |||
170 | while (IS_DIR_SEPARATOR (*d)(((*d) == '/') || (((*d) == '\\') && (0)))) | |||
171 | d++; | |||
172 | while (IS_DIR_SEPARATOR (*c)(((*c) == '/') || (((*c) == '\\') && (0)))) | |||
173 | c++; | |||
174 | size_t i; | |||
175 | for (i = 0; c[i] && !IS_DIR_SEPARATOR (c[i])(((c[i]) == '/') || (((c[i]) == '\\') && (0))) && c[i] == d[i]; i++) | |||
176 | ; | |||
177 | if ((c[i] == '\0' || IS_DIR_SEPARATOR (c[i])(((c[i]) == '/') || (((c[i]) == '\\') && (0)))) | |||
178 | && (d[i] == '\0' || IS_DIR_SEPARATOR (d[i])(((d[i]) == '/') || (((d[i]) == '\\') && (0))))) | |||
179 | { | |||
180 | c += i; | |||
181 | d += i; | |||
182 | if (*c == '\0' || *d == '\0') | |||
183 | break; | |||
184 | } | |||
185 | else | |||
186 | break; | |||
187 | } | |||
188 | while (1); | |||
189 | size_t num_up = 0; | |||
190 | do | |||
191 | { | |||
192 | while (IS_DIR_SEPARATOR (*c)(((*c) == '/') || (((*c) == '\\') && (0)))) | |||
193 | c++; | |||
194 | if (*c == '\0') | |||
195 | break; | |||
196 | num_up++; | |||
197 | while (*c && !IS_DIR_SEPARATOR (*c)(((*c) == '/') || (((*c) == '\\') && (0)))) | |||
198 | c++; | |||
199 | } | |||
200 | while (1); | |||
201 | while (IS_DIR_SEPARATOR (*d)(((*d) == '/') || (((*d) == '\\') && (0)))) | |||
202 | d++; | |||
203 | size_t len = strlen (d); | |||
204 | if (len == 0 && num_up == 0) | |||
205 | return xstrdup ("."); | |||
206 | char *ret = XNEWVEC (char, num_up * 3 + len + 1)((char *) xmalloc (sizeof (char) * (num_up * 3 + len + 1))); | |||
207 | char *p = ret; | |||
208 | for (; num_up; num_up--) | |||
209 | { | |||
210 | const char dir_up[3] = { '.', '.', DIR_SEPARATOR'/' }; | |||
211 | memcpy (p, dir_up, 3); | |||
212 | p += 3; | |||
213 | } | |||
214 | memcpy (p, d, len + 1); | |||
215 | return ret; | |||
216 | } | |||
217 | ||||
218 | /* Look up DATA_WD in hash table of relative prefixes. If found, | |||
219 | return relative path from CWD to DATA_WD from the hash table, | |||
220 | otherwise create it. */ | |||
221 | ||||
222 | static const char * | |||
223 | canon_relative_path_prefix (const char *data_wd, const char *cwd) | |||
224 | { | |||
225 | if (!IS_ABSOLUTE_PATH (data_wd)(((((data_wd)[0]) == '/') || ((((data_wd)[0]) == '\\') && (0))) || ((data_wd)[0] && ((data_wd)[1] == ':') && (0))) || !IS_ABSOLUTE_PATH (cwd)(((((cwd)[0]) == '/') || ((((cwd)[0]) == '\\') && (0) )) || ((cwd)[0] && ((cwd)[1] == ':') && (0)))) | |||
226 | return NULLnullptr; | |||
227 | ||||
228 | if (!path_name_pair_hash_table) | |||
229 | { | |||
230 | path_name_pair_hash_table | |||
231 | = new hash_table<string_pair_map_hasher> (37); | |||
232 | string_pair_map_allocator | |||
233 | = new object_allocator <struct string_pair_map> | |||
234 | ("line map string pair map hash"); | |||
235 | } | |||
236 | ||||
237 | inchash::hash h; | |||
238 | h.add_ptr (cwd); | |||
239 | h.merge_hash (htab_hash_string (data_wd)); | |||
240 | h.add_int (true); | |||
241 | ||||
242 | string_pair_map s_slot; | |||
243 | s_slot.str1 = cwd; | |||
244 | s_slot.str2 = data_wd; | |||
245 | s_slot.str3 = NULLnullptr; | |||
246 | s_slot.hash = h.end (); | |||
247 | s_slot.prefix = true; | |||
248 | ||||
249 | string_pair_map **slot | |||
250 | = path_name_pair_hash_table->find_slot (&s_slot, INSERT); | |||
251 | if (*slot == NULLnullptr) | |||
252 | { | |||
253 | /* Compute relative path from cwd directory to data_wd directory. | |||
254 | E.g. if cwd is /tmp/foo/bar and data_wd is /tmp/baz/qux , | |||
255 | it will return ../../baz/qux . */ | |||
256 | char *relative_path = relative_path_prefix (data_wd, cwd); | |||
257 | const char *relative = relative_path ? relative_path : data_wd; | |||
258 | size_t relative_len = strlen (relative); | |||
259 | gcc_assert (relative_len)((void)(!(relative_len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 259, __FUNCTION__), 0 : 0)); | |||
260 | ||||
261 | size_t data_wd_len = strlen (data_wd); | |||
262 | bool add_separator = false; | |||
263 | if (!IS_DIR_SEPARATOR (relative[relative_len - 1])(((relative[relative_len - 1]) == '/') || (((relative[relative_len - 1]) == '\\') && (0)))) | |||
264 | add_separator = true; | |||
265 | ||||
266 | size_t len = relative_len + 1 + data_wd_len + 1 + add_separator; | |||
267 | ||||
268 | char *saved_string = XOBNEWVEC (&file_name_obstack, char, len)((char *) __extension__ ({ struct obstack *__h = ((&file_name_obstack )); __extension__ ({ struct obstack *__o = (__h); size_t __len = ((sizeof (char) * (len))); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1-> next_free); }) < __len) _obstack_newchunk (__o, __len); (( void) ((__o)->next_free += (__len))); }); __extension__ ({ struct obstack *__o1 = (__h); void *__value = (void *) __o1-> object_base; if (__o1->next_free == __value) __o1->maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1->object_base) + (((__o1->next_free) - (__o1 ->object_base) + (__o1->alignment_mask)) & ~(__o1-> alignment_mask))) : (char *) (((ptrdiff_t) (__o1->next_free ) + (__o1->alignment_mask)) & ~(__o1->alignment_mask ))); if ((size_t) (__o1->next_free - (char *) __o1->chunk ) > (size_t) (__o1->chunk_limit - (char *) __o1->chunk )) __o1->next_free = __o1->chunk_limit; __o1->object_base = __o1->next_free; __value; }); })); | |||
269 | struct string_pair_map *new_slot | |||
270 | = string_pair_map_allocator->allocate (); | |||
271 | memcpy (saved_string, data_wd, data_wd_len + 1); | |||
272 | memcpy (saved_string + data_wd_len + 1, relative, relative_len); | |||
273 | if (add_separator) | |||
274 | saved_string[len - 2] = DIR_SEPARATOR'/'; | |||
275 | saved_string[len - 1] = '\0'; | |||
276 | new_slot->str1 = cwd; | |||
277 | new_slot->str2 = saved_string; | |||
278 | new_slot->str3 = saved_string + data_wd_len + 1; | |||
279 | if (relative_len == 1 && relative[0] == '.') | |||
280 | new_slot->str3 = NULLnullptr; | |||
281 | new_slot->hash = s_slot.hash; | |||
282 | new_slot->prefix = true; | |||
283 | *slot = new_slot; | |||
284 | free (relative_path); | |||
285 | return new_slot->str3; | |||
286 | } | |||
287 | else | |||
288 | { | |||
289 | string_pair_map *old_slot = *slot; | |||
290 | return old_slot->str3; | |||
291 | } | |||
292 | } | |||
293 | ||||
294 | /* Look up the pair of RELATIVE_PREFIX and STRING strings in a hash table. | |||
295 | If found, return the concatenation of those from the hash table, | |||
296 | otherwise concatenate them. */ | |||
297 | ||||
298 | static const char * | |||
299 | canon_relative_file_name (const char *relative_prefix, const char *string) | |||
300 | { | |||
301 | inchash::hash h; | |||
302 | h.add_ptr (relative_prefix); | |||
303 | h.merge_hash (htab_hash_string (string)); | |||
304 | ||||
305 | string_pair_map s_slot; | |||
306 | s_slot.str1 = relative_prefix; | |||
307 | s_slot.str2 = string; | |||
308 | s_slot.str3 = NULLnullptr; | |||
309 | s_slot.hash = h.end (); | |||
310 | s_slot.prefix = false; | |||
311 | ||||
312 | string_pair_map **slot | |||
313 | = path_name_pair_hash_table->find_slot (&s_slot, INSERT); | |||
314 | if (*slot == NULLnullptr) | |||
315 | { | |||
316 | size_t relative_prefix_len = strlen (relative_prefix); | |||
317 | size_t string_len = strlen (string); | |||
318 | size_t len = relative_prefix_len + string_len + 1; | |||
319 | ||||
320 | char *saved_string = XOBNEWVEC (&file_name_obstack, char, len)((char *) __extension__ ({ struct obstack *__h = ((&file_name_obstack )); __extension__ ({ struct obstack *__o = (__h); size_t __len = ((sizeof (char) * (len))); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1-> next_free); }) < __len) _obstack_newchunk (__o, __len); (( void) ((__o)->next_free += (__len))); }); __extension__ ({ struct obstack *__o1 = (__h); void *__value = (void *) __o1-> object_base; if (__o1->next_free == __value) __o1->maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1->object_base) + (((__o1->next_free) - (__o1 ->object_base) + (__o1->alignment_mask)) & ~(__o1-> alignment_mask))) : (char *) (((ptrdiff_t) (__o1->next_free ) + (__o1->alignment_mask)) & ~(__o1->alignment_mask ))); if ((size_t) (__o1->next_free - (char *) __o1->chunk ) > (size_t) (__o1->chunk_limit - (char *) __o1->chunk )) __o1->next_free = __o1->chunk_limit; __o1->object_base = __o1->next_free; __value; }); })); | |||
321 | struct string_pair_map *new_slot | |||
322 | = string_pair_map_allocator->allocate (); | |||
323 | memcpy (saved_string, relative_prefix, relative_prefix_len); | |||
324 | memcpy (saved_string + relative_prefix_len, string, string_len + 1); | |||
325 | new_slot->str1 = relative_prefix; | |||
326 | new_slot->str2 = saved_string + relative_prefix_len; | |||
327 | new_slot->str3 = saved_string; | |||
328 | new_slot->hash = s_slot.hash; | |||
329 | new_slot->prefix = false; | |||
330 | *slot = new_slot; | |||
331 | return new_slot->str3; | |||
332 | } | |||
333 | else | |||
334 | { | |||
335 | string_pair_map *old_slot = *slot; | |||
336 | return old_slot->str3; | |||
337 | } | |||
338 | } | |||
339 | ||||
340 | /* Lookup STRING in file_name_hash_table. If found, return the existing | |||
341 | string, otherwise insert STRING as the canonical version. | |||
342 | If STRING is a relative pathname and RELATIVE_PREFIX is non-NULL, use | |||
343 | canon_relative_file_name instead. */ | |||
344 | ||||
345 | static const char * | |||
346 | canon_file_name (const char *relative_prefix, const char *string) | |||
347 | { | |||
348 | if (relative_prefix && !IS_ABSOLUTE_PATH (string)(((((string)[0]) == '/') || ((((string)[0]) == '\\') && (0))) || ((string)[0] && ((string)[1] == ':') && (0)))) | |||
349 | return canon_relative_file_name (relative_prefix, string); | |||
350 | ||||
351 | string_slot **slot; | |||
352 | struct string_slot s_slot; | |||
353 | size_t len = strlen (string); | |||
354 | ||||
355 | s_slot.s = string; | |||
356 | s_slot.len = len; | |||
357 | ||||
358 | slot = file_name_hash_table->find_slot (&s_slot, INSERT); | |||
359 | if (*slot == NULLnullptr) | |||
360 | { | |||
361 | char *saved_string; | |||
362 | struct string_slot *new_slot; | |||
363 | ||||
364 | saved_string = XOBNEWVEC (&file_name_obstack, char, len + 1)((char *) __extension__ ({ struct obstack *__h = ((&file_name_obstack )); __extension__ ({ struct obstack *__o = (__h); size_t __len = ((sizeof (char) * (len + 1))); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->next_free); }) < __len) _obstack_newchunk (__o, __len ); ((void) ((__o)->next_free += (__len))); }); __extension__ ({ struct obstack *__o1 = (__h); void *__value = (void *) __o1 ->object_base; if (__o1->next_free == __value) __o1-> maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t ) < sizeof (void *) ? ((__o1->object_base) + (((__o1-> next_free) - (__o1->object_base) + (__o1->alignment_mask )) & ~(__o1->alignment_mask))) : (char *) (((ptrdiff_t ) (__o1->next_free) + (__o1->alignment_mask)) & ~(__o1 ->alignment_mask))); if ((size_t) (__o1->next_free - (char *) __o1->chunk) > (size_t) (__o1->chunk_limit - (char *) __o1->chunk)) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; __value; }); })); | |||
365 | new_slot = string_slot_allocator->allocate (); | |||
366 | memcpy (saved_string, string, len + 1); | |||
367 | new_slot->s = saved_string; | |||
368 | new_slot->len = len; | |||
369 | *slot = new_slot; | |||
370 | return saved_string; | |||
371 | } | |||
372 | else | |||
373 | { | |||
374 | struct string_slot *old_slot = *slot; | |||
375 | return old_slot->s; | |||
376 | } | |||
377 | } | |||
378 | ||||
379 | /* Pointer to currently alive instance of lto_location_cache. */ | |||
380 | ||||
381 | lto_location_cache *lto_location_cache::current_cache; | |||
382 | ||||
383 | /* Sort locations in source order. Start with file from last application. */ | |||
384 | ||||
385 | int | |||
386 | lto_location_cache::cmp_loc (const void *pa, const void *pb) | |||
387 | { | |||
388 | const cached_location *a = ((const cached_location *)pa); | |||
389 | const cached_location *b = ((const cached_location *)pb); | |||
390 | const char *current_file = current_cache->current_file; | |||
391 | int current_line = current_cache->current_line; | |||
392 | ||||
393 | if (a->file == current_file && b->file != current_file) | |||
394 | return -1; | |||
395 | if (a->file != current_file && b->file == current_file) | |||
396 | return 1; | |||
397 | if (a->file == current_file && b->file == current_file) | |||
398 | { | |||
399 | if (a->line == current_line && b->line != current_line) | |||
400 | return -1; | |||
401 | if (a->line != current_line && b->line == current_line) | |||
402 | return 1; | |||
403 | } | |||
404 | if (a->file != b->file) | |||
405 | return strcmp (a->file, b->file); | |||
406 | if (a->sysp != b->sysp) | |||
407 | return a->sysp ? 1 : -1; | |||
408 | if (a->line != b->line) | |||
409 | return a->line - b->line; | |||
410 | if (a->col != b->col) | |||
411 | return a->col - b->col; | |||
412 | if (a->discr != b->discr) | |||
413 | return a->discr - b->discr; | |||
414 | if ((a->block == NULL_TREE(tree) nullptr) != (b->block == NULL_TREE(tree) nullptr)) | |||
415 | return a->block ? 1 : -1; | |||
416 | if (a->block) | |||
417 | { | |||
418 | if (BLOCK_NUMBER (a->block)((tree_check ((a->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 418, __FUNCTION__, (BLOCK)))->block.block_num) < BLOCK_NUMBER (b->block)((tree_check ((b->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 418, __FUNCTION__, (BLOCK)))->block.block_num)) | |||
419 | return -1; | |||
420 | if (BLOCK_NUMBER (a->block)((tree_check ((a->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 420, __FUNCTION__, (BLOCK)))->block.block_num) > BLOCK_NUMBER (b->block)((tree_check ((b->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 420, __FUNCTION__, (BLOCK)))->block.block_num)) | |||
421 | return 1; | |||
422 | } | |||
423 | return 0; | |||
424 | } | |||
425 | ||||
426 | /* Apply all changes in location cache. Add locations into linemap and patch | |||
427 | trees. */ | |||
428 | ||||
429 | bool | |||
430 | lto_location_cache::apply_location_cache () | |||
431 | { | |||
432 | static const char *prev_file; | |||
433 | if (!loc_cache.length ()) | |||
434 | return false; | |||
435 | if (loc_cache.length () > 1) | |||
436 | loc_cache.qsort (cmp_loc)qsort (cmp_loc); | |||
437 | ||||
438 | for (unsigned int i = 0; i < loc_cache.length (); i++) | |||
439 | { | |||
440 | struct cached_location loc = loc_cache[i]; | |||
441 | ||||
442 | if (current_file != loc.file) | |||
443 | linemap_add (line_table, prev_file ? LC_RENAME : LC_ENTER, | |||
444 | loc.sysp, loc.file, loc.line); | |||
445 | else if (current_line != loc.line) | |||
446 | { | |||
447 | int max = loc.col; | |||
448 | ||||
449 | for (unsigned int j = i + 1; j < loc_cache.length (); j++) | |||
450 | if (loc.file != loc_cache[j].file | |||
451 | || loc.line != loc_cache[j].line) | |||
452 | break; | |||
453 | else if (max < loc_cache[j].col) | |||
454 | max = loc_cache[j].col; | |||
455 | linemap_line_start (line_table, loc.line, max + 1); | |||
456 | } | |||
457 | gcc_assert (*loc.loc == BUILTINS_LOCATION + 1)((void)(!(*loc.loc == ((location_t) 1) + 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 457, __FUNCTION__), 0 : 0)); | |||
458 | if (current_file != loc.file | |||
459 | || current_line != loc.line | |||
460 | || current_col != loc.col) | |||
461 | { | |||
462 | current_loc = linemap_position_for_column (line_table, loc.col); | |||
463 | if (loc.block) | |||
464 | current_loc = set_block (current_loc, loc.block); | |||
465 | if (loc.discr) | |||
466 | current_loc = location_with_discriminator (current_loc, loc.discr); | |||
467 | } | |||
468 | else if (current_block != loc.block) | |||
469 | { | |||
470 | if (loc.block) | |||
471 | current_loc = set_block (current_loc, loc.block); | |||
472 | else | |||
473 | current_loc = LOCATION_LOCUS (current_loc)((IS_ADHOC_LOC (current_loc)) ? get_location_from_adhoc_loc ( line_table, current_loc) : (current_loc)); | |||
474 | if (loc.discr) | |||
475 | current_loc = location_with_discriminator (current_loc, loc.discr); | |||
476 | } | |||
477 | else if (current_discr != loc.discr) | |||
478 | current_loc = location_with_discriminator (current_loc, loc.discr); | |||
479 | *loc.loc = current_loc; | |||
480 | current_line = loc.line; | |||
481 | prev_file = current_file = loc.file; | |||
482 | current_col = loc.col; | |||
483 | current_block = loc.block; | |||
484 | current_discr = loc.discr; | |||
485 | } | |||
486 | loc_cache.truncate (0); | |||
487 | accepted_length = 0; | |||
488 | return true; | |||
489 | } | |||
490 | ||||
491 | /* Tree merging did not succeed; mark all changes in the cache as accepted. */ | |||
492 | ||||
493 | void | |||
494 | lto_location_cache::accept_location_cache () | |||
495 | { | |||
496 | gcc_assert (current_cache == this)((void)(!(current_cache == this) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 496, __FUNCTION__), 0 : 0)); | |||
497 | accepted_length = loc_cache.length (); | |||
498 | } | |||
499 | ||||
500 | /* Tree merging did succeed; throw away recent changes. */ | |||
501 | ||||
502 | void | |||
503 | lto_location_cache::revert_location_cache () | |||
504 | { | |||
505 | loc_cache.truncate (accepted_length); | |||
506 | } | |||
507 | ||||
508 | /* Read a location bitpack from bit pack BP and either update *LOC directly | |||
509 | or add it to the location cache. If IB is non-NULL, stream in a block | |||
510 | afterwards. | |||
511 | It is neccesary to call apply_location_cache to get *LOC updated. */ | |||
512 | ||||
513 | void | |||
514 | lto_location_cache::input_location_and_block (location_t *loc, | |||
515 | struct bitpack_d *bp, | |||
516 | class lto_input_block *ib, | |||
517 | class data_in *data_in) | |||
518 | { | |||
519 | static const char *stream_file; | |||
520 | static int stream_line; | |||
521 | static int stream_col; | |||
522 | static bool stream_sysp; | |||
523 | static tree stream_block; | |||
524 | static unsigned stream_discr; | |||
525 | static const char *stream_relative_path_prefix; | |||
526 | ||||
527 | gcc_assert (current_cache == this)((void)(!(current_cache == this) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 527, __FUNCTION__), 0 : 0)); | |||
528 | ||||
529 | *loc = bp_unpack_int_in_range (bp, "location", 0, | |||
530 | RESERVED_LOCATION_COUNT + 1); | |||
531 | ||||
532 | if (*loc < RESERVED_LOCATION_COUNT) | |||
533 | { | |||
534 | if (ib) | |||
535 | { | |||
536 | bool block_change = bp_unpack_value (bp, 1); | |||
537 | if (block_change) | |||
538 | stream_block = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
539 | if (stream_block) | |||
540 | *loc = set_block (*loc, stream_block); | |||
541 | } | |||
542 | return; | |||
543 | } | |||
544 | ||||
545 | bool file_change = (*loc == RESERVED_LOCATION_COUNT + 1); | |||
546 | /* Keep value RESERVED_LOCATION_COUNT in *loc as linemap lookups will | |||
547 | ICE on it. */ | |||
548 | *loc = RESERVED_LOCATION_COUNT; | |||
549 | bool line_change = bp_unpack_value (bp, 1); | |||
550 | bool column_change = bp_unpack_value (bp, 1); | |||
551 | bool discr_change = bp_unpack_value (bp, 1); | |||
552 | ||||
553 | if (file_change) | |||
554 | { | |||
555 | bool pwd_change = bp_unpack_value (bp, 1); | |||
556 | if (pwd_change) | |||
557 | { | |||
558 | const char *pwd = bp_unpack_string (data_in, bp); | |||
559 | const char *src_pwd = get_src_pwd (); | |||
560 | if (strcmp (pwd, src_pwd) == 0) | |||
561 | stream_relative_path_prefix = NULLnullptr; | |||
562 | else | |||
563 | stream_relative_path_prefix | |||
564 | = canon_relative_path_prefix (pwd, src_pwd); | |||
565 | } | |||
566 | stream_file = canon_file_name (stream_relative_path_prefix, | |||
567 | bp_unpack_string (data_in, bp)); | |||
568 | stream_sysp = bp_unpack_value (bp, 1); | |||
569 | } | |||
570 | ||||
571 | if (line_change) | |||
572 | stream_line = bp_unpack_var_len_unsigned (bp); | |||
573 | ||||
574 | if (column_change) | |||
575 | stream_col = bp_unpack_var_len_unsigned (bp); | |||
576 | ||||
577 | if (discr_change) | |||
578 | stream_discr = bp_unpack_var_len_unsigned (bp); | |||
579 | ||||
580 | tree block = NULL_TREE(tree) nullptr; | |||
581 | if (ib) | |||
582 | { | |||
583 | bool block_change = bp_unpack_value (bp, 1); | |||
584 | if (block_change) | |||
585 | stream_block = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
586 | block = stream_block; | |||
587 | } | |||
588 | ||||
589 | /* This optimization saves location cache operations during gimple | |||
590 | streaming. */ | |||
591 | ||||
592 | if (current_file == stream_file | |||
593 | && current_line == stream_line | |||
594 | && current_col == stream_col | |||
595 | && current_sysp == stream_sysp | |||
596 | && current_discr == stream_discr) | |||
597 | { | |||
598 | if (current_block == block) | |||
599 | *loc = current_loc; | |||
600 | else if (block) | |||
601 | *loc = set_block (current_loc, block); | |||
602 | else | |||
603 | *loc = LOCATION_LOCUS (current_loc)((IS_ADHOC_LOC (current_loc)) ? get_location_from_adhoc_loc ( line_table, current_loc) : (current_loc)); | |||
604 | return; | |||
605 | } | |||
606 | ||||
607 | struct cached_location entry | |||
608 | = {stream_file, loc, stream_line, stream_col, stream_sysp, block, stream_discr}; | |||
609 | loc_cache.safe_push (entry); | |||
610 | } | |||
611 | ||||
612 | /* Read a location bitpack from bit pack BP and either update *LOC directly | |||
613 | or add it to the location cache. | |||
614 | It is neccesary to call apply_location_cache to get *LOC updated. */ | |||
615 | ||||
616 | void | |||
617 | lto_location_cache::input_location (location_t *loc, struct bitpack_d *bp, | |||
618 | class data_in *data_in) | |||
619 | { | |||
620 | return input_location_and_block (loc, bp, NULLnullptr, data_in); | |||
621 | } | |||
622 | ||||
623 | /* Read a location bitpack from input block IB and either update *LOC directly | |||
624 | or add it to the location cache. | |||
625 | It is neccesary to call apply_location_cache to get *LOC updated. */ | |||
626 | ||||
627 | void | |||
628 | lto_input_location (location_t *loc, struct bitpack_d *bp, | |||
629 | class data_in *data_in) | |||
630 | { | |||
631 | data_in->location_cache.input_location (loc, bp, data_in); | |||
632 | } | |||
633 | ||||
634 | /* Read a reference to a tree node from DATA_IN using input block IB. | |||
635 | TAG is the expected node that should be found in IB, if TAG belongs | |||
636 | to one of the indexable trees, expect to read a reference index to | |||
637 | be looked up in one of the symbol tables, otherwise read the pysical | |||
638 | representation of the tree using stream_read_tree. FN is the | |||
639 | function scope for the read tree. */ | |||
640 | ||||
641 | tree | |||
642 | lto_input_tree_ref (class lto_input_block *ib, class data_in *data_in, | |||
643 | struct function *fn, enum LTO_tags tag) | |||
644 | { | |||
645 | unsigned HOST_WIDE_INTlong ix_u; | |||
646 | tree result = NULL_TREE(tree) nullptr; | |||
647 | ||||
648 | if (tag == LTO_ssa_name_ref) | |||
649 | { | |||
650 | ix_u = streamer_read_uhwi (ib); | |||
651 | result = (*SSANAMES (fn)(fn)->gimple_df->ssa_names)[ix_u]; | |||
652 | } | |||
653 | else | |||
654 | { | |||
655 | gcc_checking_assert (tag == LTO_global_stream_ref)((void)(!(tag == LTO_global_stream_ref) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 655, __FUNCTION__), 0 : 0)); | |||
656 | ix_u = streamer_read_uhwi (ib); | |||
657 | result = (*data_in->file_data->current_decl_state | |||
658 | ->streams[LTO_DECL_STREAM])[ix_u]; | |||
659 | } | |||
660 | ||||
661 | gcc_assert (result)((void)(!(result) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 661, __FUNCTION__), 0 : 0)); | |||
662 | ||||
663 | return result; | |||
664 | } | |||
665 | ||||
666 | /* Read VAR_DECL reference to DATA from IB. */ | |||
667 | ||||
668 | tree | |||
669 | lto_input_var_decl_ref (lto_input_block *ib, lto_file_decl_data *file_data) | |||
670 | { | |||
671 | unsigned int ix_u = streamer_read_uhwi (ib); | |||
672 | tree result = (*file_data->current_decl_state | |||
673 | ->streams[LTO_DECL_STREAM])[ix_u]; | |||
674 | gcc_assert (TREE_CODE (result) == VAR_DECL)((void)(!(((enum tree_code) (result)->base.code) == VAR_DECL ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 674, __FUNCTION__), 0 : 0)); | |||
675 | return result; | |||
676 | } | |||
677 | ||||
678 | /* Read VAR_DECL reference to DATA from IB. */ | |||
679 | ||||
680 | tree | |||
681 | lto_input_fn_decl_ref (lto_input_block *ib, lto_file_decl_data *file_data) | |||
682 | { | |||
683 | unsigned int ix_u = streamer_read_uhwi (ib); | |||
684 | tree result = (*file_data->current_decl_state | |||
685 | ->streams[LTO_DECL_STREAM])[ix_u]; | |||
686 | gcc_assert (TREE_CODE (result) == FUNCTION_DECL)((void)(!(((enum tree_code) (result)->base.code) == FUNCTION_DECL ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 686, __FUNCTION__), 0 : 0)); | |||
687 | return result; | |||
688 | } | |||
689 | ||||
690 | ||||
691 | /* Read and return a double-linked list of catch handlers from input | |||
692 | block IB, using descriptors in DATA_IN. */ | |||
693 | ||||
694 | static struct eh_catch_d * | |||
695 | lto_input_eh_catch_list (class lto_input_block *ib, class data_in *data_in, | |||
696 | eh_catch *last_p) | |||
697 | { | |||
698 | eh_catch first; | |||
699 | enum LTO_tags tag; | |||
700 | ||||
701 | *last_p = first = NULLnullptr; | |||
702 | tag = streamer_read_record_start (ib); | |||
703 | while (tag) | |||
704 | { | |||
705 | tree list; | |||
706 | eh_catch n; | |||
707 | ||||
708 | lto_tag_check_range (tag, LTO_eh_catch, LTO_eh_catch); | |||
709 | ||||
710 | /* Read the catch node. */ | |||
711 | n = ggc_cleared_alloc<eh_catch_d> (); | |||
712 | n->type_list = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
713 | n->filter_list = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
714 | n->label = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
715 | ||||
716 | /* Register all the types in N->FILTER_LIST. */ | |||
717 | for (list = n->filter_list; list; list = TREE_CHAIN (list)((contains_struct_check ((list), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 717, __FUNCTION__))->common.chain)) | |||
718 | add_type_for_runtime (TREE_VALUE (list)((tree_check ((list), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 718, __FUNCTION__, (TREE_LIST)))->list.value)); | |||
719 | ||||
720 | /* Chain N to the end of the list. */ | |||
721 | if (*last_p) | |||
722 | (*last_p)->next_catch = n; | |||
723 | n->prev_catch = *last_p; | |||
724 | *last_p = n; | |||
725 | ||||
726 | /* Set the head of the list the first time through the loop. */ | |||
727 | if (first == NULLnullptr) | |||
728 | first = n; | |||
729 | ||||
730 | tag = streamer_read_record_start (ib); | |||
731 | } | |||
732 | ||||
733 | return first; | |||
734 | } | |||
735 | ||||
736 | ||||
737 | /* Read and return EH region IX from input block IB, using descriptors | |||
738 | in DATA_IN. */ | |||
739 | ||||
740 | static eh_region | |||
741 | input_eh_region (class lto_input_block *ib, class data_in *data_in, int ix) | |||
742 | { | |||
743 | enum LTO_tags tag; | |||
744 | eh_region r; | |||
745 | ||||
746 | /* Read the region header. */ | |||
747 | tag = streamer_read_record_start (ib); | |||
748 | if (tag == LTO_null) | |||
749 | return NULLnullptr; | |||
750 | ||||
751 | r = ggc_cleared_alloc<eh_region_d> (); | |||
752 | r->index = streamer_read_hwi (ib); | |||
753 | ||||
754 | gcc_assert (r->index == ix)((void)(!(r->index == ix) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 754, __FUNCTION__), 0 : 0)); | |||
755 | ||||
756 | /* Read all the region pointers as region numbers. We'll fix up | |||
757 | the pointers once the whole array has been read. */ | |||
758 | r->outer = (eh_region) (intptr_t) streamer_read_hwi (ib); | |||
759 | r->inner = (eh_region) (intptr_t) streamer_read_hwi (ib); | |||
760 | r->next_peer = (eh_region) (intptr_t) streamer_read_hwi (ib); | |||
761 | ||||
762 | switch (tag) | |||
763 | { | |||
764 | case LTO_ert_cleanup: | |||
765 | r->type = ERT_CLEANUP; | |||
766 | break; | |||
767 | ||||
768 | case LTO_ert_try: | |||
769 | { | |||
770 | struct eh_catch_d *last_catch; | |||
771 | r->type = ERT_TRY; | |||
772 | r->u.eh_try.first_catch = lto_input_eh_catch_list (ib, data_in, | |||
773 | &last_catch); | |||
774 | r->u.eh_try.last_catch = last_catch; | |||
775 | break; | |||
776 | } | |||
777 | ||||
778 | case LTO_ert_allowed_exceptions: | |||
779 | { | |||
780 | tree l; | |||
781 | ||||
782 | r->type = ERT_ALLOWED_EXCEPTIONS; | |||
783 | r->u.allowed.type_list = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
784 | r->u.allowed.label = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
785 | r->u.allowed.filter = streamer_read_uhwi (ib); | |||
786 | ||||
787 | for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l)((contains_struct_check ((l), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 787, __FUNCTION__))->common.chain)) | |||
788 | add_type_for_runtime (TREE_VALUE (l)((tree_check ((l), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 788, __FUNCTION__, (TREE_LIST)))->list.value)); | |||
789 | } | |||
790 | break; | |||
791 | ||||
792 | case LTO_ert_must_not_throw: | |||
793 | { | |||
794 | r->type = ERT_MUST_NOT_THROW; | |||
795 | r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
796 | bitpack_d bp = streamer_read_bitpack (ib); | |||
797 | stream_input_location (&r->u.must_not_throw.failure_loc,streamer_hooks.input_location (&r->u.must_not_throw.failure_loc , &bp, data_in) | |||
798 | &bp, data_in)streamer_hooks.input_location (&r->u.must_not_throw.failure_loc , &bp, data_in); | |||
799 | } | |||
800 | break; | |||
801 | ||||
802 | default: | |||
803 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 803, __FUNCTION__)); | |||
804 | } | |||
805 | ||||
806 | r->landing_pads = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib); | |||
807 | ||||
808 | return r; | |||
809 | } | |||
810 | ||||
811 | ||||
812 | /* Read and return EH landing pad IX from input block IB, using descriptors | |||
813 | in DATA_IN. */ | |||
814 | ||||
815 | static eh_landing_pad | |||
816 | input_eh_lp (class lto_input_block *ib, class data_in *data_in, int ix) | |||
817 | { | |||
818 | enum LTO_tags tag; | |||
819 | eh_landing_pad lp; | |||
820 | ||||
821 | /* Read the landing pad header. */ | |||
822 | tag = streamer_read_record_start (ib); | |||
823 | if (tag == LTO_null) | |||
824 | return NULLnullptr; | |||
825 | ||||
826 | lto_tag_check_range (tag, LTO_eh_landing_pad, LTO_eh_landing_pad); | |||
827 | ||||
828 | lp = ggc_cleared_alloc<eh_landing_pad_d> (); | |||
829 | lp->index = streamer_read_hwi (ib); | |||
830 | gcc_assert (lp->index == ix)((void)(!(lp->index == ix) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 830, __FUNCTION__), 0 : 0)); | |||
831 | lp->next_lp = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib); | |||
832 | lp->region = (eh_region) (intptr_t) streamer_read_hwi (ib); | |||
833 | lp->post_landing_pad = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
834 | ||||
835 | return lp; | |||
836 | } | |||
837 | ||||
838 | ||||
839 | /* After reading the EH regions, pointers to peer and children regions | |||
840 | are region numbers. This converts all these region numbers into | |||
841 | real pointers into the rematerialized regions for FN. ROOT_REGION | |||
842 | is the region number for the root EH region in FN. */ | |||
843 | ||||
844 | static void | |||
845 | fixup_eh_region_pointers (struct function *fn, HOST_WIDE_INTlong root_region) | |||
846 | { | |||
847 | unsigned i; | |||
848 | vec<eh_region, va_gc> *eh_array = fn->eh->region_array; | |||
849 | vec<eh_landing_pad, va_gc> *lp_array = fn->eh->lp_array; | |||
850 | eh_region r; | |||
851 | eh_landing_pad lp; | |||
852 | ||||
853 | gcc_assert (eh_array && lp_array)((void)(!(eh_array && lp_array) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 853, __FUNCTION__), 0 : 0)); | |||
854 | ||||
855 | gcc_assert (root_region >= 0)((void)(!(root_region >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 855, __FUNCTION__), 0 : 0)); | |||
856 | fn->eh->region_tree = (*eh_array)[root_region]; | |||
857 | ||||
858 | #define FIXUP_EH_REGION(r) (r) = (*eh_array)[(HOST_WIDE_INTlong) (intptr_t) (r)] | |||
859 | #define FIXUP_EH_LP(p) (p) = (*lp_array)[(HOST_WIDE_INTlong) (intptr_t) (p)] | |||
860 | ||||
861 | /* Convert all the index numbers stored in pointer fields into | |||
862 | pointers to the corresponding slots in the EH region array. */ | |||
863 | FOR_EACH_VEC_ELT (*eh_array, i, r)for (i = 0; (*eh_array).iterate ((i), &(r)); ++(i)) | |||
864 | { | |||
865 | /* The array may contain NULL regions. */ | |||
866 | if (r == NULLnullptr) | |||
867 | continue; | |||
868 | ||||
869 | gcc_assert (i == (unsigned) r->index)((void)(!(i == (unsigned) r->index) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 869, __FUNCTION__), 0 : 0)); | |||
870 | FIXUP_EH_REGION (r->outer); | |||
871 | FIXUP_EH_REGION (r->inner); | |||
872 | FIXUP_EH_REGION (r->next_peer); | |||
873 | FIXUP_EH_LP (r->landing_pads); | |||
874 | } | |||
875 | ||||
876 | /* Convert all the index numbers stored in pointer fields into | |||
877 | pointers to the corresponding slots in the EH landing pad array. */ | |||
878 | FOR_EACH_VEC_ELT (*lp_array, i, lp)for (i = 0; (*lp_array).iterate ((i), &(lp)); ++(i)) | |||
879 | { | |||
880 | /* The array may contain NULL landing pads. */ | |||
881 | if (lp == NULLnullptr) | |||
882 | continue; | |||
883 | ||||
884 | gcc_assert (i == (unsigned) lp->index)((void)(!(i == (unsigned) lp->index) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 884, __FUNCTION__), 0 : 0)); | |||
885 | FIXUP_EH_LP (lp->next_lp); | |||
886 | FIXUP_EH_REGION (lp->region); | |||
887 | } | |||
888 | ||||
889 | #undef FIXUP_EH_REGION | |||
890 | #undef FIXUP_EH_LP | |||
891 | } | |||
892 | ||||
893 | ||||
894 | /* Initialize EH support. */ | |||
895 | ||||
896 | void | |||
897 | lto_init_eh (void) | |||
898 | { | |||
899 | static bool eh_initialized_p = false; | |||
900 | ||||
901 | if (eh_initialized_p) | |||
902 | return; | |||
903 | ||||
904 | /* Contrary to most other FEs, we only initialize EH support when at | |||
905 | least one of the files in the set contains exception regions in | |||
906 | it. Since this happens much later than the call to init_eh in | |||
907 | lang_dependent_init, we have to set flag_exceptions and call | |||
908 | init_eh again to initialize the EH tables. */ | |||
909 | flag_exceptionsglobal_options.x_flag_exceptions = 1; | |||
910 | init_eh (); | |||
911 | ||||
912 | eh_initialized_p = true; | |||
913 | } | |||
914 | ||||
915 | ||||
916 | /* Read the exception table for FN from IB using the data descriptors | |||
917 | in DATA_IN. */ | |||
918 | ||||
919 | static void | |||
920 | input_eh_regions (class lto_input_block *ib, class data_in *data_in, | |||
921 | struct function *fn) | |||
922 | { | |||
923 | HOST_WIDE_INTlong i, root_region, len; | |||
924 | enum LTO_tags tag; | |||
925 | ||||
926 | tag = streamer_read_record_start (ib); | |||
927 | if (tag == LTO_null) | |||
928 | return; | |||
929 | ||||
930 | lto_tag_check_range (tag, LTO_eh_table, LTO_eh_table); | |||
931 | ||||
932 | gcc_assert (fn->eh)((void)(!(fn->eh) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 932, __FUNCTION__), 0 : 0)); | |||
933 | ||||
934 | root_region = streamer_read_hwi (ib); | |||
935 | gcc_assert (root_region == (int) root_region)((void)(!(root_region == (int) root_region) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 935, __FUNCTION__), 0 : 0)); | |||
936 | ||||
937 | /* Read the EH region array. */ | |||
938 | len = streamer_read_hwi (ib); | |||
939 | gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 939, __FUNCTION__), 0 : 0)); | |||
940 | if (len > 0) | |||
941 | { | |||
942 | vec_safe_grow_cleared (fn->eh->region_array, len, true); | |||
943 | for (i = 0; i < len; i++) | |||
944 | { | |||
945 | eh_region r = input_eh_region (ib, data_in, i); | |||
946 | (*fn->eh->region_array)[i] = r; | |||
947 | } | |||
948 | } | |||
949 | ||||
950 | /* Read the landing pads. */ | |||
951 | len = streamer_read_hwi (ib); | |||
952 | gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 952, __FUNCTION__), 0 : 0)); | |||
953 | if (len > 0) | |||
954 | { | |||
955 | vec_safe_grow_cleared (fn->eh->lp_array, len, true); | |||
956 | for (i = 0; i < len; i++) | |||
957 | { | |||
958 | eh_landing_pad lp = input_eh_lp (ib, data_in, i); | |||
959 | (*fn->eh->lp_array)[i] = lp; | |||
960 | } | |||
961 | } | |||
962 | ||||
963 | /* Read the runtime type data. */ | |||
964 | len = streamer_read_hwi (ib); | |||
965 | gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 965, __FUNCTION__), 0 : 0)); | |||
966 | if (len > 0) | |||
967 | { | |||
968 | vec_safe_grow_cleared (fn->eh->ttype_data, len, true); | |||
969 | for (i = 0; i < len; i++) | |||
970 | { | |||
971 | tree ttype = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
972 | (*fn->eh->ttype_data)[i] = ttype; | |||
973 | } | |||
974 | } | |||
975 | ||||
976 | /* Read the table of action chains. */ | |||
977 | len = streamer_read_hwi (ib); | |||
978 | gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 978, __FUNCTION__), 0 : 0)); | |||
979 | if (len > 0) | |||
980 | { | |||
981 | if (targetm.arm_eabi_unwinder) | |||
982 | { | |||
983 | vec_safe_grow_cleared (fn->eh->ehspec_data.arm_eabi, len, true); | |||
984 | for (i = 0; i < len; i++) | |||
985 | { | |||
986 | tree t = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
987 | (*fn->eh->ehspec_data.arm_eabi)[i] = t; | |||
988 | } | |||
989 | } | |||
990 | else | |||
991 | { | |||
992 | vec_safe_grow_cleared (fn->eh->ehspec_data.other, len, true); | |||
993 | for (i = 0; i < len; i++) | |||
994 | { | |||
995 | uchar c = streamer_read_uchar (ib); | |||
996 | (*fn->eh->ehspec_data.other)[i] = c; | |||
997 | } | |||
998 | } | |||
999 | } | |||
1000 | ||||
1001 | /* Reconstruct the EH region tree by fixing up the peer/children | |||
1002 | pointers. */ | |||
1003 | fixup_eh_region_pointers (fn, root_region); | |||
1004 | ||||
1005 | tag = streamer_read_record_start (ib); | |||
1006 | lto_tag_check_range (tag, LTO_null, LTO_null); | |||
1007 | } | |||
1008 | ||||
1009 | ||||
1010 | /* Make a new basic block with index INDEX in function FN. */ | |||
1011 | ||||
1012 | static basic_block | |||
1013 | make_new_block (struct function *fn, unsigned int index) | |||
1014 | { | |||
1015 | basic_block bb = alloc_block (); | |||
1016 | bb->index = index; | |||
1017 | SET_BASIC_BLOCK_FOR_FN (fn, index, bb)((*((fn)->cfg->x_basic_block_info))[(index)] = (bb)); | |||
1018 | n_basic_blocks_for_fn (fn)((fn)->cfg->x_n_basic_blocks)++; | |||
1019 | return bb; | |||
1020 | } | |||
1021 | ||||
1022 | ||||
1023 | /* Read the CFG for function FN from input block IB. */ | |||
1024 | ||||
1025 | static void | |||
1026 | input_cfg (class lto_input_block *ib, class data_in *data_in, | |||
1027 | struct function *fn) | |||
1028 | { | |||
1029 | unsigned int bb_count; | |||
1030 | basic_block p_bb; | |||
1031 | unsigned int i; | |||
1032 | int index; | |||
1033 | ||||
1034 | init_empty_tree_cfg_for_function (fn); | |||
1035 | ||||
1036 | profile_status_for_fn (fn)((fn)->cfg->x_profile_status) = streamer_read_enum (ib, profile_status_d,(enum profile_status_d)streamer_read_hwi_in_range ((ib), "profile_status_d" , 0, (int)(PROFILE_LAST) - 1) | |||
1037 | PROFILE_LAST)(enum profile_status_d)streamer_read_hwi_in_range ((ib), "profile_status_d" , 0, (int)(PROFILE_LAST) - 1); | |||
1038 | ||||
1039 | bb_count = streamer_read_uhwi (ib); | |||
1040 | ||||
1041 | last_basic_block_for_fn (fn)((fn)->cfg->x_last_basic_block) = bb_count; | |||
1042 | if (bb_count > basic_block_info_for_fn (fn)((fn)->cfg->x_basic_block_info)->length ()) | |||
1043 | vec_safe_grow_cleared (basic_block_info_for_fn (fn)((fn)->cfg->x_basic_block_info), bb_count, true); | |||
1044 | ||||
1045 | if (bb_count > label_to_block_map_for_fn (fn)((fn)->cfg->x_label_to_block_map)->length ()) | |||
1046 | vec_safe_grow_cleared (label_to_block_map_for_fn (fn)((fn)->cfg->x_label_to_block_map), bb_count, true); | |||
1047 | ||||
1048 | index = streamer_read_hwi (ib); | |||
1049 | while (index != -1) | |||
1050 | { | |||
1051 | basic_block bb = BASIC_BLOCK_FOR_FN (fn, index)((*((fn)->cfg->x_basic_block_info))[(index)]); | |||
1052 | unsigned int edge_count; | |||
1053 | ||||
1054 | if (bb == NULLnullptr) | |||
1055 | bb = make_new_block (fn, index); | |||
1056 | ||||
1057 | edge_count = streamer_read_uhwi (ib); | |||
1058 | ||||
1059 | /* Connect up the CFG. */ | |||
1060 | for (i = 0; i < edge_count; i++) | |||
1061 | { | |||
1062 | bitpack_d bp = streamer_read_bitpack (ib); | |||
1063 | unsigned int dest_index = bp_unpack_var_len_unsigned (&bp); | |||
1064 | unsigned int edge_flags = bp_unpack_var_len_unsigned (&bp); | |||
1065 | basic_block dest = BASIC_BLOCK_FOR_FN (fn, dest_index)((*((fn)->cfg->x_basic_block_info))[(dest_index)]); | |||
1066 | ||||
1067 | if (dest == NULLnullptr) | |||
1068 | dest = make_new_block (fn, dest_index); | |||
1069 | ||||
1070 | edge e = make_edge (bb, dest, edge_flags); | |||
1071 | data_in->location_cache.input_location_and_block (&e->goto_locus, | |||
1072 | &bp, ib, data_in); | |||
1073 | e->probability = profile_probability::stream_in (ib); | |||
1074 | ||||
1075 | } | |||
1076 | ||||
1077 | index = streamer_read_hwi (ib); | |||
1078 | } | |||
1079 | ||||
1080 | p_bb = ENTRY_BLOCK_PTR_FOR_FN (fn)((fn)->cfg->x_entry_block_ptr); | |||
1081 | index = streamer_read_hwi (ib); | |||
1082 | while (index != -1) | |||
1083 | { | |||
1084 | basic_block bb = BASIC_BLOCK_FOR_FN (fn, index)((*((fn)->cfg->x_basic_block_info))[(index)]); | |||
1085 | bb->prev_bb = p_bb; | |||
1086 | p_bb->next_bb = bb; | |||
1087 | p_bb = bb; | |||
1088 | index = streamer_read_hwi (ib); | |||
1089 | } | |||
1090 | ||||
1091 | /* ??? The cfgloop interface is tied to cfun. */ | |||
1092 | gcc_assert (cfun == fn)((void)(!((cfun + 0) == fn) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1092, __FUNCTION__), 0 : 0)); | |||
1093 | ||||
1094 | /* Input the loop tree. */ | |||
1095 | unsigned n_loops = streamer_read_uhwi (ib); | |||
1096 | if (n_loops == 0) | |||
1097 | return; | |||
1098 | ||||
1099 | struct loops *loops = ggc_cleared_alloc<struct loops> (); | |||
1100 | init_loops_structure (fn, loops, n_loops); | |||
1101 | set_loops_for_fn (fn, loops); | |||
1102 | ||||
1103 | /* Input each loop and associate it with its loop header so | |||
1104 | flow_loops_find can rebuild the loop tree. */ | |||
1105 | for (unsigned i = 1; i < n_loops; ++i) | |||
1106 | { | |||
1107 | int header_index = streamer_read_hwi (ib); | |||
1108 | if (header_index == -1) | |||
1109 | { | |||
1110 | loops->larray->quick_push (NULLnullptr); | |||
1111 | continue; | |||
1112 | } | |||
1113 | ||||
1114 | class loop *loop = alloc_loop (); | |||
1115 | loop->header = BASIC_BLOCK_FOR_FN (fn, header_index)((*((fn)->cfg->x_basic_block_info))[(header_index)]); | |||
1116 | loop->header->loop_father = loop; | |||
1117 | ||||
1118 | /* Read everything copy_loop_info copies. */ | |||
1119 | loop->estimate_state = streamer_read_enum (ib, loop_estimation, EST_LAST)(enum loop_estimation)streamer_read_hwi_in_range ((ib), "loop_estimation" , 0, (int)(EST_LAST) - 1); | |||
1120 | loop->any_upper_bound = streamer_read_hwi (ib); | |||
1121 | if (loop->any_upper_bound) | |||
1122 | loop->nb_iterations_upper_bound = streamer_read_widest_int (ib); | |||
1123 | loop->any_likely_upper_bound = streamer_read_hwi (ib); | |||
1124 | if (loop->any_likely_upper_bound) | |||
1125 | loop->nb_iterations_likely_upper_bound = streamer_read_widest_int (ib); | |||
1126 | loop->any_estimate = streamer_read_hwi (ib); | |||
1127 | if (loop->any_estimate) | |||
1128 | loop->nb_iterations_estimate = streamer_read_widest_int (ib); | |||
1129 | ||||
1130 | /* Read OMP SIMD related info. */ | |||
1131 | loop->safelen = streamer_read_hwi (ib); | |||
1132 | loop->unroll = streamer_read_hwi (ib); | |||
1133 | loop->owned_clique = streamer_read_hwi (ib); | |||
1134 | loop->dont_vectorize = streamer_read_hwi (ib); | |||
1135 | loop->force_vectorize = streamer_read_hwi (ib); | |||
1136 | loop->finite_p = streamer_read_hwi (ib); | |||
1137 | loop->simduid = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1138 | ||||
1139 | place_new_loop (fn, loop); | |||
1140 | ||||
1141 | /* flow_loops_find doesn't like loops not in the tree, hook them | |||
1142 | all as siblings of the tree root temporarily. */ | |||
1143 | flow_loop_tree_node_add (loops->tree_root, loop); | |||
1144 | } | |||
1145 | ||||
1146 | /* Rebuild the loop tree. */ | |||
1147 | flow_loops_find (loops); | |||
1148 | } | |||
1149 | ||||
1150 | ||||
1151 | /* Read the SSA names array for function FN from DATA_IN using input | |||
1152 | block IB. */ | |||
1153 | ||||
1154 | static void | |||
1155 | input_ssa_names (class lto_input_block *ib, class data_in *data_in, | |||
1156 | struct function *fn) | |||
1157 | { | |||
1158 | unsigned int i, size; | |||
1159 | ||||
1160 | size = streamer_read_uhwi (ib); | |||
1161 | init_tree_ssa (fn, size); | |||
1162 | cfun(cfun + 0)->gimple_df->in_ssa_p = true; | |||
1163 | init_ssa_operands (fn); | |||
1164 | ||||
1165 | i = streamer_read_uhwi (ib); | |||
1166 | while (i) | |||
1167 | { | |||
1168 | tree ssa_name, name; | |||
1169 | bool is_default_def; | |||
1170 | ||||
1171 | /* Skip over the elements that had been freed. */ | |||
1172 | while (SSANAMES (fn)(fn)->gimple_df->ssa_names->length () < i) | |||
1173 | SSANAMES (fn)(fn)->gimple_df->ssa_names->quick_push (NULL_TREE(tree) nullptr); | |||
1174 | ||||
1175 | is_default_def = (streamer_read_uchar (ib) != 0); | |||
1176 | name = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1177 | ssa_name = make_ssa_name_fn (fn, name, NULLnullptr); | |||
1178 | ||||
1179 | if (is_default_def) | |||
1180 | { | |||
1181 | set_ssa_default_def (cfun(cfun + 0), SSA_NAME_VAR (ssa_name)((tree_check ((ssa_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1181, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree) nullptr || ((enum tree_code) ((ssa_name)->ssa_name.var)-> base.code) == IDENTIFIER_NODE ? (tree) nullptr : (ssa_name)-> ssa_name.var), ssa_name); | |||
1182 | SSA_NAME_DEF_STMT (ssa_name)(tree_check ((ssa_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1182, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt = gimple_build_nop (); | |||
1183 | } | |||
1184 | ||||
1185 | i = streamer_read_uhwi (ib); | |||
1186 | } | |||
1187 | } | |||
1188 | ||||
1189 | ||||
1190 | /* Go through all NODE edges and fixup call_stmt pointers | |||
1191 | so they point to STMTS. */ | |||
1192 | ||||
1193 | static void | |||
1194 | fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple **stmts, | |||
1195 | struct function *fn) | |||
1196 | { | |||
1197 | #define STMT_UID_NOT_IN_RANGE(uid)(gimple_stmt_max_uid (fn) < uid || uid == 0) \ | |||
1198 | (gimple_stmt_max_uid (fn) < uid || uid == 0) | |||
1199 | ||||
1200 | struct cgraph_edge *cedge; | |||
1201 | struct ipa_ref *ref = NULLnullptr; | |||
1202 | unsigned int i; | |||
1203 | ||||
1204 | for (cedge = node->callees; cedge; cedge = cedge->next_callee) | |||
1205 | { | |||
1206 | if (STMT_UID_NOT_IN_RANGE (cedge->lto_stmt_uid)(gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid || cedge ->lto_stmt_uid == 0)) | |||
1207 | fatal_error (input_location, | |||
1208 | "Cgraph edge statement index out of range"); | |||
1209 | cedge->call_stmt = as_a <gcall *> (stmts[cedge->lto_stmt_uid - 1]); | |||
1210 | cedge->lto_stmt_uid = 0; | |||
1211 | if (!cedge->call_stmt) | |||
1212 | fatal_error (input_location, | |||
1213 | "Cgraph edge statement index not found"); | |||
1214 | } | |||
1215 | for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee) | |||
1216 | { | |||
1217 | if (STMT_UID_NOT_IN_RANGE (cedge->lto_stmt_uid)(gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid || cedge ->lto_stmt_uid == 0)) | |||
1218 | fatal_error (input_location, | |||
1219 | "Cgraph edge statement index out of range"); | |||
1220 | cedge->call_stmt = as_a <gcall *> (stmts[cedge->lto_stmt_uid - 1]); | |||
1221 | cedge->lto_stmt_uid = 0; | |||
1222 | if (!cedge->call_stmt) | |||
1223 | fatal_error (input_location, "Cgraph edge statement index not found"); | |||
1224 | } | |||
1225 | for (i = 0; node->iterate_reference (i, ref); i++) | |||
1226 | if (ref->lto_stmt_uid) | |||
1227 | { | |||
1228 | if (STMT_UID_NOT_IN_RANGE (ref->lto_stmt_uid)(gimple_stmt_max_uid (fn) < ref->lto_stmt_uid || ref-> lto_stmt_uid == 0)) | |||
1229 | fatal_error (input_location, | |||
1230 | "Reference statement index out of range"); | |||
1231 | ref->stmt = stmts[ref->lto_stmt_uid - 1]; | |||
1232 | ref->lto_stmt_uid = 0; | |||
1233 | if (!ref->stmt) | |||
1234 | fatal_error (input_location, "Reference statement index not found"); | |||
1235 | } | |||
1236 | } | |||
1237 | ||||
1238 | ||||
1239 | /* Fixup call_stmt pointers in NODE and all clones. */ | |||
1240 | ||||
1241 | static void | |||
1242 | fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts) | |||
1243 | { | |||
1244 | struct cgraph_node *node; | |||
1245 | struct function *fn; | |||
1246 | ||||
1247 | while (orig->clone_of) | |||
1248 | orig = orig->clone_of; | |||
1249 | fn = DECL_STRUCT_FUNCTION (orig->decl)((tree_check ((orig->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1249, __FUNCTION__, (FUNCTION_DECL)))->function_decl.f); | |||
1250 | ||||
1251 | if (!orig->thunk) | |||
1252 | fixup_call_stmt_edges_1 (orig, stmts, fn); | |||
1253 | if (orig->clones) | |||
1254 | for (node = orig->clones; node != orig;) | |||
1255 | { | |||
1256 | if (!node->thunk) | |||
1257 | fixup_call_stmt_edges_1 (node, stmts, fn); | |||
1258 | if (node->clones) | |||
1259 | node = node->clones; | |||
1260 | else if (node->next_sibling_clone) | |||
1261 | node = node->next_sibling_clone; | |||
1262 | else | |||
1263 | { | |||
1264 | while (node != orig && !node->next_sibling_clone) | |||
1265 | node = node->clone_of; | |||
1266 | if (node != orig) | |||
1267 | node = node->next_sibling_clone; | |||
1268 | } | |||
1269 | } | |||
1270 | } | |||
1271 | ||||
1272 | ||||
1273 | /* Input the base body of struct function FN from DATA_IN | |||
1274 | using input block IB. */ | |||
1275 | ||||
1276 | static void | |||
1277 | input_struct_function_base (struct function *fn, class data_in *data_in, | |||
1278 | class lto_input_block *ib) | |||
1279 | { | |||
1280 | struct bitpack_d bp; | |||
1281 | int len; | |||
1282 | ||||
1283 | /* Read the static chain and non-local goto save area. */ | |||
1284 | fn->static_chain_decl = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1285 | fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1286 | ||||
1287 | /* Read all the local symbols. */ | |||
1288 | len = streamer_read_hwi (ib); | |||
1289 | if (len > 0) | |||
1290 | { | |||
1291 | int i; | |||
1292 | vec_safe_grow_cleared (fn->local_decls, len, true); | |||
1293 | for (i = 0; i < len; i++) | |||
1294 | { | |||
1295 | tree t = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1296 | (*fn->local_decls)[i] = t; | |||
1297 | } | |||
1298 | } | |||
1299 | ||||
1300 | /* Input the current IL state of the function. */ | |||
1301 | fn->curr_properties = streamer_read_uhwi (ib); | |||
1302 | ||||
1303 | /* Read all the attributes for FN. */ | |||
1304 | bp = streamer_read_bitpack (ib); | |||
1305 | fn->is_thunk = bp_unpack_value (&bp, 1); | |||
1306 | fn->has_local_explicit_reg_vars = bp_unpack_value (&bp, 1); | |||
1307 | fn->returns_pcc_struct = bp_unpack_value (&bp, 1); | |||
1308 | fn->returns_struct = bp_unpack_value (&bp, 1); | |||
1309 | fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1); | |||
1310 | fn->can_delete_dead_exceptions = bp_unpack_value (&bp, 1); | |||
1311 | fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1); | |||
1312 | fn->after_inlining = bp_unpack_value (&bp, 1); | |||
1313 | fn->stdarg = bp_unpack_value (&bp, 1); | |||
1314 | fn->has_nonlocal_label = bp_unpack_value (&bp, 1); | |||
1315 | fn->has_forced_label_in_static = bp_unpack_value (&bp, 1); | |||
1316 | fn->calls_alloca = bp_unpack_value (&bp, 1); | |||
1317 | fn->calls_setjmp = bp_unpack_value (&bp, 1); | |||
1318 | fn->calls_eh_return = bp_unpack_value (&bp, 1); | |||
1319 | fn->has_force_vectorize_loops = bp_unpack_value (&bp, 1); | |||
1320 | fn->has_simduid_loops = bp_unpack_value (&bp, 1); | |||
1321 | fn->assume_function = bp_unpack_value (&bp, 1); | |||
1322 | fn->va_list_fpr_size = bp_unpack_value (&bp, 8); | |||
1323 | fn->va_list_gpr_size = bp_unpack_value (&bp, 8); | |||
1324 | fn->last_clique = bp_unpack_value (&bp, sizeof (short) * 8); | |||
1325 | ||||
1326 | /* Input the function start and end loci. */ | |||
1327 | stream_input_location (&fn->function_start_locus, &bp, data_in)streamer_hooks.input_location (&fn->function_start_locus , &bp, data_in); | |||
1328 | stream_input_location (&fn->function_end_locus, &bp, data_in)streamer_hooks.input_location (&fn->function_end_locus , &bp, data_in); | |||
1329 | ||||
1330 | /* Restore the instance discriminators if present. */ | |||
1331 | int instance_number = bp_unpack_value (&bp, 1); | |||
1332 | if (instance_number) | |||
1333 | { | |||
1334 | instance_number = bp_unpack_value (&bp, sizeof (int) * CHAR_BIT8); | |||
1335 | maybe_create_decl_to_instance_map ()->put (fn->decl, instance_number); | |||
1336 | } | |||
1337 | } | |||
1338 | ||||
1339 | /* Read a chain of tree nodes from input block IB. DATA_IN contains | |||
1340 | tables and descriptors for the file being read. */ | |||
1341 | ||||
1342 | static tree | |||
1343 | streamer_read_chain (class lto_input_block *ib, class data_in *data_in) | |||
1344 | { | |||
1345 | tree first, prev, curr; | |||
1346 | ||||
1347 | /* The chain is written as NULL terminated list of trees. */ | |||
1348 | first = prev = NULL_TREE(tree) nullptr; | |||
1349 | do | |||
1350 | { | |||
1351 | curr = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1352 | if (prev) | |||
1353 | TREE_CHAIN (prev)((contains_struct_check ((prev), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1353, __FUNCTION__))->common.chain) = curr; | |||
1354 | else | |||
1355 | first = curr; | |||
1356 | ||||
1357 | prev = curr; | |||
1358 | } | |||
1359 | while (curr); | |||
1360 | ||||
1361 | return first; | |||
1362 | } | |||
1363 | ||||
1364 | /* Read the body of function FN_DECL from DATA_IN using input block IB. */ | |||
1365 | ||||
1366 | static void | |||
1367 | input_function (tree fn_decl, class data_in *data_in, | |||
1368 | class lto_input_block *ib, class lto_input_block *ib_cfg, | |||
1369 | cgraph_node *node) | |||
1370 | { | |||
1371 | struct function *fn; | |||
1372 | enum LTO_tags tag; | |||
1373 | gimple **stmts; | |||
1374 | basic_block bb; | |||
1375 | ||||
1376 | tag = streamer_read_record_start (ib); | |||
1377 | lto_tag_check (tag, LTO_function); | |||
1378 | ||||
1379 | /* Read decls for parameters and args. */ | |||
1380 | DECL_RESULT (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1380, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result ) = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1381 | DECL_ARGUMENTS (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1381, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ) = streamer_read_chain (ib, data_in); | |||
1382 | ||||
1383 | /* Read debug args if available. */ | |||
1384 | unsigned n_debugargs = streamer_read_uhwi (ib); | |||
1385 | if (n_debugargs) | |||
1386 | { | |||
1387 | vec<tree, va_gc> **debugargs = decl_debug_args_insert (fn_decl); | |||
1388 | vec_safe_grow (*debugargs, n_debugargs, true); | |||
1389 | for (unsigned i = 0; i < n_debugargs; ++i) | |||
1390 | (**debugargs)[i] = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1391 | } | |||
1392 | ||||
1393 | /* Read the tree of lexical scopes for the function. */ | |||
1394 | DECL_INITIAL (fn_decl)((contains_struct_check ((fn_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1394, __FUNCTION__))->decl_common.initial) = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1395 | unsigned block_leaf_count = streamer_read_uhwi (ib); | |||
1396 | while (block_leaf_count--) | |||
1397 | stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1398 | ||||
1399 | if (!streamer_read_uhwi (ib)) | |||
1400 | return; | |||
1401 | ||||
1402 | push_struct_function (fn_decl); | |||
1403 | fn = DECL_STRUCT_FUNCTION (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1403, __FUNCTION__, (FUNCTION_DECL)))->function_decl.f); | |||
1404 | ||||
1405 | gimple_register_cfg_hooks (); | |||
1406 | ||||
1407 | input_struct_function_base (fn, data_in, ib); | |||
1408 | input_cfg (ib_cfg, data_in, fn); | |||
1409 | ||||
1410 | /* Read all the SSA names. */ | |||
1411 | input_ssa_names (ib, data_in, fn); | |||
1412 | ||||
1413 | /* Read the exception handling regions in the function. */ | |||
1414 | input_eh_regions (ib, data_in, fn); | |||
1415 | ||||
1416 | gcc_assert (DECL_INITIAL (fn_decl))((void)(!(((contains_struct_check ((fn_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1416, __FUNCTION__))->decl_common.initial)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1416, __FUNCTION__), 0 : 0)); | |||
1417 | DECL_SAVED_TREE (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1417, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree ) = NULL_TREE(tree) nullptr; | |||
1418 | ||||
1419 | /* Read all the basic blocks. */ | |||
1420 | tag = streamer_read_record_start (ib); | |||
1421 | while (tag) | |||
1422 | { | |||
1423 | input_bb (ib, tag, data_in, fn, | |||
1424 | node->count_materialization_scale); | |||
1425 | tag = streamer_read_record_start (ib); | |||
1426 | } | |||
1427 | ||||
1428 | /* Finalize gimple_location/gimple_block of stmts and phis. */ | |||
1429 | data_in->location_cache.apply_location_cache (); | |||
1430 | ||||
1431 | /* Fix up the call statements that are mentioned in the callgraph | |||
1432 | edges. */ | |||
1433 | set_gimple_stmt_max_uid (cfun(cfun + 0), 0); | |||
1434 | FOR_ALL_BB_FN (bb, cfun)for (bb = (((cfun + 0))->cfg->x_entry_block_ptr); bb; bb = bb->next_bb) | |||
1435 | { | |||
1436 | gimple_stmt_iterator gsi; | |||
1437 | for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |||
1438 | { | |||
1439 | gimple *stmt = gsi_stmt (gsi); | |||
1440 | gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun(cfun + 0))); | |||
1441 | } | |||
1442 | for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |||
1443 | { | |||
1444 | gimple *stmt = gsi_stmt (gsi); | |||
1445 | gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun(cfun + 0))); | |||
1446 | } | |||
1447 | } | |||
1448 | stmts = (gimple **) xcalloc (gimple_stmt_max_uid (fn), sizeof (gimple *)); | |||
1449 | FOR_ALL_BB_FN (bb, cfun)for (bb = (((cfun + 0))->cfg->x_entry_block_ptr); bb; bb = bb->next_bb) | |||
1450 | { | |||
1451 | gimple_stmt_iterator bsi = gsi_start_phis (bb); | |||
1452 | while (!gsi_end_p (bsi)) | |||
1453 | { | |||
1454 | gimple *stmt = gsi_stmt (bsi); | |||
1455 | gsi_next (&bsi); | |||
1456 | stmts[gimple_uid (stmt)] = stmt; | |||
1457 | } | |||
1458 | bsi = gsi_start_bb (bb); | |||
1459 | while (!gsi_end_p (bsi)) | |||
1460 | { | |||
1461 | gimple *stmt = gsi_stmt (bsi); | |||
1462 | bool remove = false; | |||
1463 | /* If we're recompiling LTO objects with debug stmts but | |||
1464 | we're not supposed to have debug stmts, remove them now. | |||
1465 | We can't remove them earlier because this would cause uid | |||
1466 | mismatches in fixups, but we can do it at this point, as | |||
1467 | long as debug stmts don't require fixups. | |||
1468 | Similarly remove all IFN_*SAN_* internal calls */ | |||
1469 | if (!flag_wpaglobal_options.x_flag_wpa) | |||
1470 | { | |||
1471 | if (is_gimple_debug (stmt) | |||
1472 | && (gimple_debug_nonbind_marker_p (stmt) | |||
1473 | ? !MAY_HAVE_DEBUG_MARKER_STMTSglobal_options.x_debug_nonbind_markers_p | |||
1474 | : !MAY_HAVE_DEBUG_BIND_STMTSglobal_options.x_flag_var_tracking_assignments)) | |||
1475 | remove = true; | |||
1476 | /* In case the linemap overflows locations can be dropped | |||
1477 | to zero. Thus do not keep nonsensical inline entry markers | |||
1478 | we'd later ICE on. */ | |||
1479 | tree block; | |||
1480 | if (gimple_debug_inline_entry_p (stmt) | |||
1481 | && (((block = gimple_block (stmt)) | |||
1482 | && !inlined_function_outer_scope_p (block)) | |||
1483 | || !debug_inline_pointsglobal_options.x_debug_inline_points)) | |||
1484 | remove = true; | |||
1485 | if (is_gimple_call (stmt) | |||
1486 | && gimple_call_internal_p (stmt)) | |||
1487 | { | |||
1488 | bool replace = false; | |||
1489 | switch (gimple_call_internal_fn (stmt)) | |||
1490 | { | |||
1491 | case IFN_UBSAN_NULL: | |||
1492 | if ((flag_sanitizeglobal_options.x_flag_sanitize | |||
1493 | & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) == 0) | |||
1494 | replace = true; | |||
1495 | break; | |||
1496 | case IFN_UBSAN_BOUNDS: | |||
1497 | if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_BOUNDS) == 0) | |||
1498 | replace = true; | |||
1499 | break; | |||
1500 | case IFN_UBSAN_VPTR: | |||
1501 | if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_VPTR) == 0) | |||
1502 | replace = true; | |||
1503 | break; | |||
1504 | case IFN_UBSAN_OBJECT_SIZE: | |||
1505 | if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_OBJECT_SIZE) == 0) | |||
1506 | replace = true; | |||
1507 | break; | |||
1508 | case IFN_UBSAN_PTR: | |||
1509 | if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_POINTER_OVERFLOW) == 0) | |||
1510 | replace = true; | |||
1511 | break; | |||
1512 | case IFN_ASAN_MARK: | |||
1513 | if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_ADDRESS) == 0) | |||
1514 | replace = true; | |||
1515 | break; | |||
1516 | case IFN_TSAN_FUNC_EXIT: | |||
1517 | if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_THREAD) == 0) | |||
1518 | replace = true; | |||
1519 | break; | |||
1520 | default: | |||
1521 | break; | |||
1522 | } | |||
1523 | if (replace) | |||
1524 | { | |||
1525 | gimple_call_set_internal_fn (as_a <gcall *> (stmt), | |||
1526 | IFN_NOP); | |||
1527 | update_stmt (stmt); | |||
1528 | } | |||
1529 | } | |||
1530 | } | |||
1531 | if (remove) | |||
1532 | { | |||
1533 | gimple_stmt_iterator gsi = bsi; | |||
1534 | gsi_next (&bsi); | |||
1535 | unlink_stmt_vdef (stmt); | |||
1536 | release_defs (stmt); | |||
1537 | gsi_remove (&gsi, true); | |||
1538 | } | |||
1539 | else | |||
1540 | { | |||
1541 | gsi_next (&bsi); | |||
1542 | stmts[gimple_uid (stmt)] = stmt; | |||
1543 | ||||
1544 | /* Remember that the input function has begin stmt | |||
1545 | markers, so that we know to expect them when emitting | |||
1546 | debug info. */ | |||
1547 | if (!cfun(cfun + 0)->debug_nonbind_markers | |||
1548 | && gimple_debug_nonbind_marker_p (stmt)) | |||
1549 | cfun(cfun + 0)->debug_nonbind_markers = true; | |||
1550 | } | |||
1551 | } | |||
1552 | } | |||
1553 | ||||
1554 | /* Set the gimple body to the statement sequence in the entry | |||
1555 | basic block. FIXME lto, this is fairly hacky. The existence | |||
1556 | of a gimple body is used by the cgraph routines, but we should | |||
1557 | really use the presence of the CFG. */ | |||
1558 | { | |||
1559 | edge_iterator ei = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)ei_start_1 (&((((cfun + 0))->cfg->x_entry_block_ptr )->succs)); | |||
1560 | gimple_set_body (fn_decl, bb_seq (ei_edge (ei)->dest)); | |||
1561 | } | |||
1562 | ||||
1563 | update_max_bb_count (); | |||
1564 | fixup_call_stmt_edges (node, stmts); | |||
1565 | execute_all_ipa_stmt_fixups (node, stmts); | |||
1566 | ||||
1567 | free_dominance_info (CDI_DOMINATORS); | |||
1568 | free_dominance_info (CDI_POST_DOMINATORS); | |||
1569 | free (stmts); | |||
1570 | pop_cfun (); | |||
1571 | } | |||
1572 | ||||
1573 | /* Read the body of function FN_DECL from DATA_IN using input block IB. */ | |||
1574 | ||||
1575 | static void | |||
1576 | input_constructor (tree var, class data_in *data_in, | |||
1577 | class lto_input_block *ib) | |||
1578 | { | |||
1579 | DECL_INITIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1579, __FUNCTION__))->decl_common.initial) = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in); | |||
1580 | } | |||
1581 | ||||
1582 | ||||
1583 | /* Read the body from DATA for function NODE and fill it in. | |||
1584 | FILE_DATA are the global decls and types. SECTION_TYPE is either | |||
1585 | LTO_section_function_body or LTO_section_static_initializer. If | |||
1586 | section type is LTO_section_function_body, FN must be the decl for | |||
1587 | that function. */ | |||
1588 | ||||
1589 | static void | |||
1590 | lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symtab_node *node, | |||
1591 | const char *data, enum lto_section_type section_type) | |||
1592 | { | |||
1593 | const struct lto_function_header *header; | |||
1594 | class data_in *data_in; | |||
1595 | int cfg_offset; | |||
1596 | int main_offset; | |||
1597 | int string_offset; | |||
1598 | tree fn_decl = node->decl; | |||
1599 | ||||
1600 | header = (const struct lto_function_header *) data; | |||
1601 | if (TREE_CODE (node->decl)((enum tree_code) (node->decl)->base.code) == FUNCTION_DECL) | |||
1602 | { | |||
1603 | cfg_offset = sizeof (struct lto_function_header); | |||
1604 | main_offset = cfg_offset + header->cfg_size; | |||
1605 | string_offset = main_offset + header->main_size; | |||
1606 | } | |||
1607 | else | |||
1608 | { | |||
1609 | main_offset = sizeof (struct lto_function_header); | |||
1610 | string_offset = main_offset + header->main_size; | |||
1611 | } | |||
1612 | ||||
1613 | data_in = lto_data_in_create (file_data, data + string_offset, | |||
1614 | header->string_size, vNULL); | |||
1615 | ||||
1616 | if (section_type
| |||
1617 | { | |||
1618 | struct lto_in_decl_state *decl_state; | |||
1619 | unsigned from; | |||
1620 | ||||
1621 | gcc_checking_assert (node)((void)(!(node) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1621, __FUNCTION__), 0 : 0)); | |||
1622 | ||||
1623 | /* Use the function's decl state. */ | |||
1624 | decl_state = lto_get_function_in_decl_state (file_data, fn_decl); | |||
1625 | gcc_assert (decl_state)((void)(!(decl_state) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1625, __FUNCTION__), 0 : 0)); | |||
1626 | file_data->current_decl_state = decl_state; | |||
1627 | ||||
1628 | ||||
1629 | /* Set up the struct function. */ | |||
1630 | from = data_in->reader_cache->nodes.length (); | |||
1631 | lto_input_block ib_main (data + main_offset, header->main_size, | |||
1632 | file_data->mode_table); | |||
1633 | if (TREE_CODE (node->decl)((enum tree_code) (node->decl)->base.code) == FUNCTION_DECL) | |||
1634 | { | |||
1635 | lto_input_block ib_cfg (data + cfg_offset, header->cfg_size, | |||
| ||||
1636 | file_data->mode_table); | |||
1637 | input_function (fn_decl, data_in, &ib_main, &ib_cfg, | |||
1638 | dyn_cast <cgraph_node *>(node)); | |||
1639 | } | |||
1640 | else | |||
1641 | input_constructor (fn_decl, data_in, &ib_main); | |||
1642 | data_in->location_cache.apply_location_cache (); | |||
1643 | /* And fixup types we streamed locally. */ | |||
1644 | { | |||
1645 | struct streamer_tree_cache_d *cache = data_in->reader_cache; | |||
1646 | unsigned len = cache->nodes.length (); | |||
1647 | unsigned i; | |||
1648 | for (i = len; i-- > from;) | |||
1649 | { | |||
1650 | tree t = streamer_tree_cache_get_tree (cache, i); | |||
1651 | if (t == NULL_TREE(tree) nullptr) | |||
1652 | continue; | |||
1653 | ||||
1654 | if (TYPE_P (t)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (t)->base.code))] == tcc_type)) | |||
1655 | { | |||
1656 | gcc_assert (TYPE_CANONICAL (t) == NULL_TREE)((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1656, __FUNCTION__))->type_common.canonical) == (tree) nullptr ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1656, __FUNCTION__), 0 : 0)); | |||
1657 | if (type_with_alias_set_p (t) | |||
1658 | && canonical_type_used_p (t)) | |||
1659 | TYPE_CANONICAL (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1659, __FUNCTION__))->type_common.canonical) = TYPE_MAIN_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1659, __FUNCTION__))->type_common.main_variant); | |||
1660 | if (TYPE_MAIN_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1660, __FUNCTION__))->type_common.main_variant) != t) | |||
1661 | { | |||
1662 | gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE)((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1662, __FUNCTION__))->type_common.next_variant) == (tree ) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1662, __FUNCTION__), 0 : 0)); | |||
1663 | TYPE_NEXT_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1663, __FUNCTION__))->type_common.next_variant) | |||
1664 | = TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t))((tree_class_check ((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1664, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1664, __FUNCTION__))->type_common.next_variant); | |||
1665 | TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t))((tree_class_check ((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1665, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1665, __FUNCTION__))->type_common.next_variant) = t; | |||
1666 | } | |||
1667 | } | |||
1668 | } | |||
1669 | } | |||
1670 | ||||
1671 | /* Restore decl state */ | |||
1672 | file_data->current_decl_state = file_data->global_decl_state; | |||
1673 | } | |||
1674 | ||||
1675 | lto_data_in_delete (data_in); | |||
1676 | } | |||
1677 | ||||
1678 | ||||
1679 | /* Read the body of NODE using DATA. FILE_DATA holds the global | |||
1680 | decls and types. */ | |||
1681 | ||||
1682 | void | |||
1683 | lto_input_function_body (struct lto_file_decl_data *file_data, | |||
1684 | struct cgraph_node *node, const char *data) | |||
1685 | { | |||
1686 | lto_read_body_or_constructor (file_data, node, data, LTO_section_function_body); | |||
1687 | } | |||
1688 | ||||
1689 | /* Read the body of NODE using DATA. FILE_DATA holds the global | |||
1690 | decls and types. */ | |||
1691 | ||||
1692 | void | |||
1693 | lto_input_variable_constructor (struct lto_file_decl_data *file_data, | |||
1694 | struct varpool_node *node, const char *data) | |||
1695 | { | |||
1696 | lto_read_body_or_constructor (file_data, node, data, LTO_section_function_body); | |||
| ||||
1697 | } | |||
1698 | ||||
1699 | ||||
1700 | /* Queue of acummulated decl -> DIE mappings. Similar to locations those | |||
1701 | are only applied to prevailing tree nodes during tree merging. */ | |||
1702 | vec<dref_entry> dref_queue; | |||
1703 | ||||
1704 | /* Read the physical representation of a tree node EXPR from | |||
1705 | input block IB using the per-file context in DATA_IN. */ | |||
1706 | ||||
1707 | static void | |||
1708 | lto_read_tree_1 (class lto_input_block *ib, class data_in *data_in, tree expr) | |||
1709 | { | |||
1710 | /* Read all the bitfield values in EXPR. Note that for LTO, we | |||
1711 | only write language-independent bitfields, so no more unpacking is | |||
1712 | needed. */ | |||
1713 | streamer_read_tree_bitfields (ib, data_in, expr); | |||
1714 | ||||
1715 | /* Read all the pointer fields in EXPR. */ | |||
1716 | streamer_read_tree_body (ib, data_in, expr); | |||
1717 | ||||
1718 | /* Read any LTO-specific data not read by the tree streamer. Do not use | |||
1719 | stream_read_tree here since that flushes the dref_queue in mids of | |||
1720 | SCC reading. */ | |||
1721 | if (DECL_P (expr)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (expr)->base.code))] == tcc_declaration) | |||
1722 | && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != FUNCTION_DECL | |||
1723 | && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != TRANSLATION_UNIT_DECL) | |||
1724 | DECL_INITIAL (expr)((contains_struct_check ((expr), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1724, __FUNCTION__))->decl_common.initial) | |||
1725 | = lto_input_tree_1 (ib, data_in, streamer_read_record_start (ib), 0); | |||
1726 | ||||
1727 | /* Stream references to early generated DIEs. Keep in sync with the | |||
1728 | trees handled in dwarf2out_register_external_die. */ | |||
1729 | if ((DECL_P (expr)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (expr)->base.code))] == tcc_declaration) | |||
1730 | && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != FIELD_DECL | |||
1731 | && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != DEBUG_EXPR_DECL | |||
1732 | && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != TYPE_DECL) | |||
1733 | || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == BLOCK) | |||
1734 | { | |||
1735 | const char *str = streamer_read_string (data_in, ib); | |||
1736 | if (str) | |||
1737 | { | |||
1738 | unsigned HOST_WIDE_INTlong off = streamer_read_uhwi (ib); | |||
1739 | dref_entry e = { expr, str, off }; | |||
1740 | dref_queue.safe_push (e); | |||
1741 | } | |||
1742 | } | |||
1743 | } | |||
1744 | ||||
1745 | /* Read the physical representation of a tree node with tag TAG from | |||
1746 | input block IB using the per-file context in DATA_IN. */ | |||
1747 | ||||
1748 | static tree | |||
1749 | lto_read_tree (class lto_input_block *ib, class data_in *data_in, | |||
1750 | enum LTO_tags tag, hashval_t hash) | |||
1751 | { | |||
1752 | /* Instantiate a new tree node. */ | |||
1753 | tree result = streamer_alloc_tree (ib, data_in, tag); | |||
1754 | ||||
1755 | /* Enter RESULT in the reader cache. This will make RESULT | |||
1756 | available so that circular references in the rest of the tree | |||
1757 | structure can be resolved in subsequent calls to stream_read_tree. */ | |||
1758 | streamer_tree_cache_append (data_in->reader_cache, result, hash); | |||
1759 | ||||
1760 | lto_read_tree_1 (ib, data_in, result); | |||
1761 | ||||
1762 | return result; | |||
1763 | } | |||
1764 | ||||
1765 | ||||
1766 | /* Populate the reader cache with trees materialized from the SCC | |||
1767 | following in the IB, DATA_IN stream. | |||
1768 | If SHARED_SCC is true we input LTO_tree_scc. */ | |||
1769 | ||||
1770 | hashval_t | |||
1771 | lto_input_scc (class lto_input_block *ib, class data_in *data_in, | |||
1772 | unsigned *len, unsigned *entry_len, bool shared_scc) | |||
1773 | { | |||
1774 | unsigned size = streamer_read_uhwi (ib); | |||
1775 | hashval_t scc_hash = 0; | |||
1776 | unsigned scc_entry_len = 1; | |||
1777 | ||||
1778 | if (shared_scc) | |||
1779 | { | |||
1780 | if (size & 1) | |||
1781 | scc_entry_len = streamer_read_uhwi (ib); | |||
1782 | size /= 2; | |||
1783 | scc_hash = streamer_read_uhwi (ib); | |||
1784 | } | |||
1785 | ||||
1786 | if (size == 1) | |||
1787 | { | |||
1788 | enum LTO_tags tag = streamer_read_record_start (ib); | |||
1789 | lto_input_tree_1 (ib, data_in, tag, scc_hash); | |||
1790 | } | |||
1791 | else | |||
1792 | { | |||
1793 | unsigned int first = data_in->reader_cache->nodes.length (); | |||
1794 | tree result; | |||
1795 | ||||
1796 | /* Materialize size trees by reading their headers. */ | |||
1797 | for (unsigned i = 0; i < size; ++i) | |||
1798 | { | |||
1799 | enum LTO_tags tag = streamer_read_record_start (ib); | |||
1800 | if (tag == LTO_null | |||
1801 | || tag == LTO_global_stream_ref | |||
1802 | || tag == LTO_tree_pickle_reference | |||
1803 | || tag == LTO_integer_cst | |||
1804 | || tag == LTO_tree_scc | |||
1805 | || tag == LTO_trees) | |||
1806 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1806, __FUNCTION__)); | |||
1807 | ||||
1808 | result = streamer_alloc_tree (ib, data_in, tag); | |||
1809 | streamer_tree_cache_append (data_in->reader_cache, result, 0); | |||
1810 | } | |||
1811 | ||||
1812 | /* Read the tree bitpacks and references. */ | |||
1813 | for (unsigned i = 0; i < size; ++i) | |||
1814 | { | |||
1815 | result = streamer_tree_cache_get_tree (data_in->reader_cache, | |||
1816 | first + i); | |||
1817 | lto_read_tree_1 (ib, data_in, result); | |||
1818 | } | |||
1819 | } | |||
1820 | ||||
1821 | *len = size; | |||
1822 | *entry_len = scc_entry_len; | |||
1823 | return scc_hash; | |||
1824 | } | |||
1825 | ||||
1826 | /* Read reference to tree from IB and DATA_IN. | |||
1827 | This is used for streaming tree bodies where we know that | |||
1828 | the tree is already in cache or is indexable and | |||
1829 | must be matched with stream_write_tree_ref. */ | |||
1830 | ||||
1831 | tree | |||
1832 | stream_read_tree_ref (lto_input_block *ib, data_in *data_in) | |||
1833 | { | |||
1834 | int ix = streamer_read_hwi (ib); | |||
1835 | if (!ix) | |||
1836 | return NULL_TREE(tree) nullptr; | |||
1837 | if (ix > 0) | |||
1838 | return streamer_tree_cache_get_tree (data_in->reader_cache, ix - 1); | |||
1839 | ||||
1840 | ix = -ix - 1; | |||
1841 | int id = ix & 1; | |||
1842 | ix /= 2; | |||
1843 | ||||
1844 | tree ret; | |||
1845 | if (!id) | |||
1846 | ret = (*data_in->file_data->current_decl_state | |||
1847 | ->streams[LTO_DECL_STREAM])[ix]; | |||
1848 | else | |||
1849 | ret = (*SSANAMES (cfun)((cfun + 0))->gimple_df->ssa_names)[ix]; | |||
1850 | return ret; | |||
1851 | } | |||
1852 | ||||
1853 | /* Read a tree from input block IB using the per-file context in | |||
1854 | DATA_IN. This context is used, for example, to resolve references | |||
1855 | to previously read nodes. */ | |||
1856 | ||||
1857 | tree | |||
1858 | lto_input_tree_1 (class lto_input_block *ib, class data_in *data_in, | |||
1859 | enum LTO_tags tag, hashval_t hash) | |||
1860 | { | |||
1861 | tree result; | |||
1862 | ||||
1863 | gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS)((void)(!((unsigned) tag < (unsigned) LTO_NUM_TAGS) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1863, __FUNCTION__), 0 : 0)); | |||
1864 | ||||
1865 | if (tag == LTO_null) | |||
1866 | result = NULL_TREE(tree) nullptr; | |||
1867 | else if (tag == LTO_global_stream_ref || tag == LTO_ssa_name_ref) | |||
1868 | { | |||
1869 | /* If TAG is a reference to an indexable tree, the next value | |||
1870 | in IB is the index into the table where we expect to find | |||
1871 | that tree. */ | |||
1872 | result = lto_input_tree_ref (ib, data_in, cfun(cfun + 0), tag); | |||
1873 | } | |||
1874 | else if (tag == LTO_tree_pickle_reference) | |||
1875 | { | |||
1876 | /* If TAG is a reference to a previously read tree, look it up in | |||
1877 | the reader cache. */ | |||
1878 | result = streamer_get_pickled_tree (ib, data_in); | |||
1879 | } | |||
1880 | else if (tag == LTO_integer_cst) | |||
1881 | { | |||
1882 | /* For shared integer constants in singletons we can use the | |||
1883 | existing tree integer constant merging code. */ | |||
1884 | tree type = stream_read_tree_ref (ib, data_in); | |||
1885 | unsigned HOST_WIDE_INTlong len = streamer_read_uhwi (ib); | |||
1886 | unsigned HOST_WIDE_INTlong i; | |||
1887 | HOST_WIDE_INTlong a[WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64)]; | |||
1888 | ||||
1889 | for (i = 0; i < len; i++) | |||
1890 | a[i] = streamer_read_hwi (ib); | |||
1891 | gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT)((void)(!(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1891, __FUNCTION__))->type_common.precision) <= (64*( 8))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1891, __FUNCTION__), 0 : 0)); | |||
1892 | result = wide_int_to_tree (type, wide_int::from_array | |||
1893 | (a, len, TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1893, __FUNCTION__))->type_common.precision))); | |||
1894 | streamer_tree_cache_append (data_in->reader_cache, result, hash); | |||
1895 | } | |||
1896 | else if (tag == LTO_tree_scc || tag == LTO_trees) | |||
1897 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1897, __FUNCTION__)); | |||
1898 | else | |||
1899 | { | |||
1900 | /* Otherwise, materialize a new node from IB. */ | |||
1901 | result = lto_read_tree (ib, data_in, tag, hash); | |||
1902 | } | |||
1903 | ||||
1904 | return result; | |||
1905 | } | |||
1906 | ||||
1907 | tree | |||
1908 | lto_input_tree (class lto_input_block *ib, class data_in *data_in) | |||
1909 | { | |||
1910 | enum LTO_tags tag; | |||
1911 | ||||
1912 | /* Input pickled trees needed to stream in the reference. */ | |||
1913 | while ((tag = streamer_read_record_start (ib)) == LTO_trees) | |||
1914 | { | |||
1915 | unsigned len, entry_len; | |||
1916 | lto_input_scc (ib, data_in, &len, &entry_len, false); | |||
1917 | ||||
1918 | /* Register DECLs with the debuginfo machinery. */ | |||
1919 | while (!dref_queue.is_empty ()) | |||
1920 | { | |||
1921 | dref_entry e = dref_queue.pop (); | |||
1922 | debug_hooks->register_external_die (e.decl, e.sym, e.off); | |||
1923 | } | |||
1924 | } | |||
1925 | tree t = lto_input_tree_1 (ib, data_in, tag, 0); | |||
1926 | ||||
1927 | if (!dref_queue.is_empty ()) | |||
1928 | { | |||
1929 | dref_entry e = dref_queue.pop (); | |||
1930 | debug_hooks->register_external_die (e.decl, e.sym, e.off); | |||
1931 | gcc_checking_assert (dref_queue.is_empty ())((void)(!(dref_queue.is_empty ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 1931, __FUNCTION__), 0 : 0)); | |||
1932 | } | |||
1933 | return t; | |||
1934 | } | |||
1935 | ||||
1936 | ||||
1937 | /* Input toplevel asms. */ | |||
1938 | ||||
1939 | void | |||
1940 | lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base) | |||
1941 | { | |||
1942 | size_t len; | |||
1943 | const char *data | |||
1944 | = lto_get_summary_section_data (file_data, LTO_section_asm, &len); | |||
1945 | const struct lto_simple_header_with_strings *header | |||
1946 | = (const struct lto_simple_header_with_strings *) data; | |||
1947 | int string_offset; | |||
1948 | class data_in *data_in; | |||
1949 | tree str; | |||
1950 | ||||
1951 | if (! data) | |||
1952 | return; | |||
1953 | ||||
1954 | string_offset = sizeof (*header) + header->main_size; | |||
1955 | ||||
1956 | lto_input_block ib (data + sizeof (*header), header->main_size, | |||
1957 | file_data->mode_table); | |||
1958 | ||||
1959 | data_in = lto_data_in_create (file_data, data + string_offset, | |||
1960 | header->string_size, vNULL); | |||
1961 | ||||
1962 | while ((str = streamer_read_string_cst (data_in, &ib))) | |||
1963 | { | |||
1964 | asm_node *node = symtab->finalize_toplevel_asm (str); | |||
1965 | node->order = streamer_read_hwi (&ib) + order_base; | |||
1966 | if (node->order >= symtab->order) | |||
1967 | symtab->order = node->order + 1; | |||
1968 | } | |||
1969 | ||||
1970 | lto_data_in_delete (data_in); | |||
1971 | ||||
1972 | lto_free_section_data (file_data, LTO_section_asm, NULLnullptr, data, len); | |||
1973 | } | |||
1974 | ||||
1975 | ||||
1976 | /* Input mode table. */ | |||
1977 | ||||
1978 | void | |||
1979 | lto_input_mode_table (struct lto_file_decl_data *file_data) | |||
1980 | { | |||
1981 | size_t len; | |||
1982 | const char *data | |||
1983 | = lto_get_summary_section_data (file_data, LTO_section_mode_table, &len); | |||
1984 | if (! data) | |||
1985 | internal_error ("cannot read LTO mode table from %s", | |||
1986 | file_data->file_name); | |||
1987 | ||||
1988 | unsigned char *table = ggc_cleared_vec_alloc<unsigned char> (1 << 8); | |||
1989 | file_data->mode_table = table; | |||
1990 | const struct lto_simple_header_with_strings *header | |||
1991 | = (const struct lto_simple_header_with_strings *) data; | |||
1992 | int string_offset; | |||
1993 | class data_in *data_in; | |||
1994 | string_offset = sizeof (*header) + header->main_size; | |||
1995 | ||||
1996 | lto_input_block ib (data + sizeof (*header), header->main_size, NULLnullptr); | |||
1997 | data_in = lto_data_in_create (file_data, data + string_offset, | |||
1998 | header->string_size, vNULL); | |||
1999 | bitpack_d bp = streamer_read_bitpack (&ib); | |||
2000 | ||||
2001 | table[VOIDmode((void) 0, E_VOIDmode)] = VOIDmode((void) 0, E_VOIDmode); | |||
2002 | table[BLKmode((void) 0, E_BLKmode)] = BLKmode((void) 0, E_BLKmode); | |||
2003 | unsigned int m; | |||
2004 | while ((m = bp_unpack_value (&bp, 8)) != VOIDmode((void) 0, E_VOIDmode)) | |||
2005 | { | |||
2006 | enum mode_class mclass | |||
2007 | = bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS)(enum mode_class)bp_unpack_int_in_range ((&bp), "mode_class" , 0, (int)(MAX_MODE_CLASS) - 1); | |||
2008 | poly_uint16 size = bp_unpack_poly_value (&bp, 16); | |||
2009 | poly_uint16 prec = bp_unpack_poly_value (&bp, 16); | |||
2010 | machine_mode inner = (machine_mode) bp_unpack_value (&bp, 8); | |||
2011 | poly_uint16 nunits = bp_unpack_poly_value (&bp, 16); | |||
2012 | unsigned int ibit = 0, fbit = 0; | |||
2013 | unsigned int real_fmt_len = 0; | |||
2014 | const char *real_fmt_name = NULLnullptr; | |||
2015 | switch (mclass) | |||
2016 | { | |||
2017 | case MODE_FRACT: | |||
2018 | case MODE_UFRACT: | |||
2019 | case MODE_ACCUM: | |||
2020 | case MODE_UACCUM: | |||
2021 | ibit = bp_unpack_value (&bp, 8); | |||
2022 | fbit = bp_unpack_value (&bp, 8); | |||
2023 | break; | |||
2024 | case MODE_FLOAT: | |||
2025 | case MODE_DECIMAL_FLOAT: | |||
2026 | real_fmt_name = bp_unpack_indexed_string (data_in, &bp, | |||
2027 | &real_fmt_len); | |||
2028 | break; | |||
2029 | default: | |||
2030 | break; | |||
2031 | } | |||
2032 | /* First search just the GET_CLASS_NARROWEST_MODE to wider modes, | |||
2033 | if not found, fallback to all modes. */ | |||
2034 | int pass; | |||
2035 | for (pass = 0; pass < 2; pass++) | |||
2036 | for (machine_mode mr = pass ? VOIDmode((void) 0, E_VOIDmode) | |||
2037 | : GET_CLASS_NARROWEST_MODE (mclass)((machine_mode) class_narrowest_mode[mclass]); | |||
2038 | pass ? mr < MAX_MACHINE_MODE : mr != VOIDmode((void) 0, E_VOIDmode); | |||
2039 | pass ? mr = (machine_mode) (mr + 1) | |||
2040 | : mr = GET_MODE_WIDER_MODE (mr).else_void ()) | |||
2041 | if (GET_MODE_CLASS (mr)((enum mode_class) mode_class[mr]) != mclass | |||
2042 | || maybe_ne (GET_MODE_SIZE (mr), size) | |||
2043 | || maybe_ne (GET_MODE_PRECISION (mr), prec) | |||
2044 | || (inner == m | |||
2045 | ? GET_MODE_INNER (mr)(mode_to_inner (mr)) != mr | |||
2046 | : GET_MODE_INNER (mr)(mode_to_inner (mr)) != table[(int) inner]) | |||
2047 | || GET_MODE_IBIT (mr)mode_ibit[mr] != ibit | |||
2048 | || GET_MODE_FBIT (mr)mode_fbit[mr] != fbit | |||
2049 | || maybe_ne (GET_MODE_NUNITS (mr), nunits)) | |||
2050 | continue; | |||
2051 | else if ((mclass == MODE_FLOAT || mclass == MODE_DECIMAL_FLOAT) | |||
2052 | && strcmp (REAL_MODE_FORMAT (mr)(real_format_for_mode[(((enum mode_class) mode_class[mr]) == MODE_DECIMAL_FLOAT ) ? (((mr) - MIN_MODE_DECIMAL_FLOAT) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) : ((enum mode_class) mode_class[mr]) == MODE_FLOAT ? ( (mr) - MIN_MODE_FLOAT) : ((fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc" , 2052, __FUNCTION__)), 0)])->name, real_fmt_name) != 0) | |||
2053 | continue; | |||
2054 | else | |||
2055 | { | |||
2056 | table[m] = mr; | |||
2057 | pass = 2; | |||
2058 | break; | |||
2059 | } | |||
2060 | unsigned int mname_len; | |||
2061 | const char *mname = bp_unpack_indexed_string (data_in, &bp, &mname_len); | |||
2062 | if (pass == 2) | |||
2063 | { | |||
2064 | switch (mclass) | |||
2065 | { | |||
2066 | case MODE_VECTOR_BOOL: | |||
2067 | case MODE_VECTOR_INT: | |||
2068 | case MODE_VECTOR_FLOAT: | |||
2069 | case MODE_VECTOR_FRACT: | |||
2070 | case MODE_VECTOR_UFRACT: | |||
2071 | case MODE_VECTOR_ACCUM: | |||
2072 | case MODE_VECTOR_UACCUM: | |||
2073 | /* For unsupported vector modes just use BLKmode, | |||
2074 | if the scalar mode is supported. */ | |||
2075 | if (table[(int) inner] != VOIDmode((void) 0, E_VOIDmode)) | |||
2076 | { | |||
2077 | table[m] = BLKmode((void) 0, E_BLKmode); | |||
2078 | break; | |||
2079 | } | |||
2080 | /* FALLTHRU */ | |||
2081 | default: | |||
2082 | /* This is only used for offloading-target compilations and | |||
2083 | is a user-facing error. Give a better error message for | |||
2084 | the common modes; see also mode-classes.def. */ | |||
2085 | if (mclass == MODE_FLOAT) | |||
2086 | fatal_error (UNKNOWN_LOCATION((location_t) 0), | |||
2087 | "%s - %u-bit-precision floating-point numbers " | |||
2088 | "unsupported (mode %qs)", TARGET_MACHINE"x86_64-pc-linux-gnu", | |||
2089 | prec.to_constant (), mname); | |||
2090 | else if (mclass == MODE_DECIMAL_FLOAT) | |||
2091 | fatal_error (UNKNOWN_LOCATION((location_t) 0), | |||
2092 | "%s - %u-bit-precision decimal floating-point " | |||
2093 | "numbers unsupported (mode %qs)", TARGET_MACHINE"x86_64-pc-linux-gnu", | |||
2094 | prec.to_constant (), mname); | |||
2095 | else if (mclass == MODE_COMPLEX_FLOAT) | |||
2096 | fatal_error (UNKNOWN_LOCATION((location_t) 0), | |||
2097 | "%s - %u-bit-precision complex floating-point " | |||
2098 | "numbers unsupported (mode %qs)", TARGET_MACHINE"x86_64-pc-linux-gnu", | |||
2099 | prec.to_constant (), mname); | |||
2100 | else if (mclass == MODE_INT) | |||
2101 | fatal_error (UNKNOWN_LOCATION((location_t) 0), | |||
2102 | "%s - %u-bit integer numbers unsupported (mode " | |||
2103 | "%qs)", TARGET_MACHINE"x86_64-pc-linux-gnu", prec.to_constant (), mname); | |||
2104 | else | |||
2105 | fatal_error (UNKNOWN_LOCATION((location_t) 0), "%s - unsupported mode %qs", | |||
2106 | TARGET_MACHINE"x86_64-pc-linux-gnu", mname); | |||
2107 | break; | |||
2108 | } | |||
2109 | } | |||
2110 | } | |||
2111 | lto_data_in_delete (data_in); | |||
2112 | ||||
2113 | lto_free_section_data (file_data, LTO_section_mode_table, NULLnullptr, data, len); | |||
2114 | } | |||
2115 | ||||
2116 | ||||
2117 | /* Initialization for the LTO reader. */ | |||
2118 | ||||
2119 | void | |||
2120 | lto_reader_init (void) | |||
2121 | { | |||
2122 | lto_streamer_init (); | |||
2123 | file_name_hash_table | |||
2124 | = new hash_table<string_slot_hasher> (37); | |||
2125 | string_slot_allocator = new object_allocator <struct string_slot> | |||
2126 | ("line map file name hash"); | |||
2127 | gcc_obstack_init (&file_name_obstack)_obstack_begin (((&file_name_obstack)), (memory_block_pool ::block_size), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free )); | |||
2128 | } | |||
2129 | ||||
2130 | /* Free hash table used to stream in location file names. */ | |||
2131 | ||||
2132 | void | |||
2133 | lto_free_file_name_hash (void) | |||
2134 | { | |||
2135 | delete file_name_hash_table; | |||
2136 | file_name_hash_table = NULLnullptr; | |||
2137 | delete string_slot_allocator; | |||
2138 | string_slot_allocator = NULLnullptr; | |||
2139 | delete path_name_pair_hash_table; | |||
2140 | path_name_pair_hash_table = NULLnullptr; | |||
2141 | delete string_pair_map_allocator; | |||
2142 | string_pair_map_allocator = NULLnullptr; | |||
2143 | /* file_name_obstack must stay allocated since it is referred to by | |||
2144 | line map table. */ | |||
2145 | } | |||
2146 | ||||
2147 | ||||
2148 | /* Create a new data_in object for FILE_DATA. STRINGS is the string | |||
2149 | table to use with LEN strings. RESOLUTIONS is the vector of linker | |||
2150 | resolutions (NULL if not using a linker plugin). */ | |||
2151 | ||||
2152 | class data_in * | |||
2153 | lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings, | |||
2154 | unsigned len, | |||
2155 | vec<ld_plugin_symbol_resolution_t> resolutions) | |||
2156 | { | |||
2157 | class data_in *data_in = new (class data_in); | |||
2158 | data_in->file_data = file_data; | |||
2159 | data_in->strings = strings; | |||
2160 | data_in->strings_len = len; | |||
2161 | data_in->globals_resolution = resolutions; | |||
2162 | data_in->reader_cache = streamer_tree_cache_create (false, false, true); | |||
2163 | return data_in; | |||
2164 | } | |||
2165 | ||||
2166 | ||||
2167 | /* Remove DATA_IN. */ | |||
2168 | ||||
2169 | void | |||
2170 | lto_data_in_delete (class data_in *data_in) | |||
2171 | { | |||
2172 | data_in->globals_resolution.release (); | |||
2173 | streamer_tree_cache_delete (data_in->reader_cache); | |||
2174 | delete data_in; | |||
2175 | } |