]>
Commit | Line | Data |
---|---|---|
2aae7680 | 1 | /* Symbol table. |
d1e082c2 | 2 | Copyright (C) 2012-2013 Free Software Foundation, Inc. |
2aae7680 JH |
3 | Contributed by Jan Hubicka |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 3, or (at your option) any later | |
10 | version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING3. If not see | |
19 | <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | #include "config.h" | |
22 | #include "system.h" | |
23 | #include "coretypes.h" | |
24 | #include "tm.h" | |
25 | #include "tree.h" | |
26 | #include "tree-inline.h" | |
8f940ee6 | 27 | #include "langhooks.h" |
2aae7680 | 28 | #include "hashtab.h" |
1ab24192 | 29 | #include "ggc.h" |
2aae7680 | 30 | #include "cgraph.h" |
1ab24192 | 31 | #include "diagnostic.h" |
474ffc72 | 32 | #include "timevar.h" |
65d630d4 JH |
33 | #include "lto-streamer.h" |
34 | #include "rtl.h" | |
35 | ||
36 | const char * const ld_plugin_symbol_resolution_names[]= | |
37 | { | |
38 | "", | |
39 | "undef", | |
40 | "prevailing_def", | |
41 | "prevailing_def_ironly", | |
42 | "preempted_reg", | |
43 | "preempted_ir", | |
44 | "resolved_ir", | |
45 | "resolved_exec", | |
46 | "resolved_dyn", | |
47 | "prevailing_def_ironly_exp" | |
48 | }; | |
1ab24192 JH |
49 | |
50 | /* Hash table used to convert declarations into nodes. */ | |
51 | static GTY((param_is (union symtab_node_def))) htab_t symtab_hash; | |
52 | /* Hash table used to convert assembler names into nodes. */ | |
53 | static GTY((param_is (union symtab_node_def))) htab_t assembler_name_hash; | |
2aae7680 JH |
54 | |
55 | /* Linked list of symbol table nodes. */ | |
56 | symtab_node symtab_nodes; | |
57 | ||
58 | /* The order index of the next symtab node to be created. This is | |
59 | used so that we can sort the cgraph nodes in order by when we saw | |
60 | them, to support -fno-toplevel-reorder. */ | |
61 | int symtab_order; | |
62 | ||
1ab24192 JH |
63 | /* Returns a hash code for P. */ |
64 | ||
65 | static hashval_t | |
66 | hash_node (const void *p) | |
67 | { | |
68 | const_symtab_node n = (const_symtab_node ) p; | |
69 | return (hashval_t) DECL_UID (n->symbol.decl); | |
70 | } | |
71 | ||
72 | ||
73 | /* Returns nonzero if P1 and P2 are equal. */ | |
74 | ||
75 | static int | |
76 | eq_node (const void *p1, const void *p2) | |
77 | { | |
78 | const_symtab_node n1 = (const_symtab_node) p1; | |
79 | const_symtab_node n2 = (const_symtab_node) p2; | |
80 | return DECL_UID (n1->symbol.decl) == DECL_UID (n2->symbol.decl); | |
81 | } | |
82 | ||
83 | /* Returns a hash code for P. */ | |
84 | ||
85 | static hashval_t | |
86 | hash_node_by_assembler_name (const void *p) | |
87 | { | |
88 | const_symtab_node n = (const_symtab_node) p; | |
89 | return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->symbol.decl)); | |
90 | } | |
91 | ||
92 | /* Returns nonzero if P1 and P2 are equal. */ | |
93 | ||
94 | static int | |
95 | eq_assembler_name (const void *p1, const void *p2) | |
96 | { | |
97 | const_symtab_node n1 = (const_symtab_node) p1; | |
98 | const_tree name = (const_tree)p2; | |
99 | return (decl_assembler_name_equal (n1->symbol.decl, name)); | |
100 | } | |
101 | ||
102 | /* Insert NODE to assembler name hash. */ | |
103 | ||
104 | static void | |
c3167b00 | 105 | insert_to_assembler_name_hash (symtab_node node, bool with_clones) |
1ab24192 | 106 | { |
5d59b5e1 | 107 | if (is_a <varpool_node> (node) && DECL_HARD_REGISTER (node->symbol.decl)) |
b5493fb2 | 108 | return; |
1ab24192 JH |
109 | gcc_checking_assert (!node->symbol.previous_sharing_asm_name |
110 | && !node->symbol.next_sharing_asm_name); | |
111 | if (assembler_name_hash) | |
112 | { | |
113 | void **aslot; | |
c3167b00 JH |
114 | struct cgraph_node *cnode; |
115 | tree decl = node->symbol.decl; | |
116 | ||
1ab24192 JH |
117 | tree name = DECL_ASSEMBLER_NAME (node->symbol.decl); |
118 | ||
119 | aslot = htab_find_slot_with_hash (assembler_name_hash, name, | |
120 | decl_assembler_name_hash (name), | |
121 | INSERT); | |
122 | gcc_assert (*aslot != node); | |
123 | node->symbol.next_sharing_asm_name = (symtab_node)*aslot; | |
124 | if (*aslot != NULL) | |
125 | ((symtab_node)*aslot)->symbol.previous_sharing_asm_name = node; | |
126 | *aslot = node; | |
c3167b00 JH |
127 | |
128 | /* Update also possible inline clones sharing a decl. */ | |
129 | cnode = dyn_cast <cgraph_node> (node); | |
130 | if (cnode && cnode->clones && with_clones) | |
131 | for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone) | |
132 | if (cnode->symbol.decl == decl) | |
133 | insert_to_assembler_name_hash ((symtab_node) cnode, true); | |
1ab24192 JH |
134 | } |
135 | ||
136 | } | |
137 | ||
138 | /* Remove NODE from assembler name hash. */ | |
139 | ||
140 | static void | |
c3167b00 | 141 | unlink_from_assembler_name_hash (symtab_node node, bool with_clones) |
1ab24192 JH |
142 | { |
143 | if (assembler_name_hash) | |
144 | { | |
c3167b00 JH |
145 | struct cgraph_node *cnode; |
146 | tree decl = node->symbol.decl; | |
147 | ||
1ab24192 JH |
148 | if (node->symbol.next_sharing_asm_name) |
149 | node->symbol.next_sharing_asm_name->symbol.previous_sharing_asm_name | |
150 | = node->symbol.previous_sharing_asm_name; | |
151 | if (node->symbol.previous_sharing_asm_name) | |
152 | { | |
153 | node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name | |
154 | = node->symbol.next_sharing_asm_name; | |
155 | } | |
156 | else | |
157 | { | |
158 | tree name = DECL_ASSEMBLER_NAME (node->symbol.decl); | |
159 | void **slot; | |
160 | slot = htab_find_slot_with_hash (assembler_name_hash, name, | |
161 | decl_assembler_name_hash (name), | |
162 | NO_INSERT); | |
163 | gcc_assert (*slot == node); | |
164 | if (!node->symbol.next_sharing_asm_name) | |
165 | htab_clear_slot (assembler_name_hash, slot); | |
166 | else | |
167 | *slot = node->symbol.next_sharing_asm_name; | |
168 | } | |
b5493fb2 JH |
169 | node->symbol.next_sharing_asm_name = NULL; |
170 | node->symbol.previous_sharing_asm_name = NULL; | |
c3167b00 JH |
171 | |
172 | /* Update also possible inline clones sharing a decl. */ | |
173 | cnode = dyn_cast <cgraph_node> (node); | |
174 | if (cnode && cnode->clones && with_clones) | |
175 | for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone) | |
176 | if (cnode->symbol.decl == decl) | |
177 | unlink_from_assembler_name_hash ((symtab_node) cnode, true); | |
1ab24192 JH |
178 | } |
179 | } | |
180 | ||
b5493fb2 JH |
181 | /* Arrange node to be first in its entry of assembler_name_hash. */ |
182 | ||
183 | void | |
184 | symtab_prevail_in_asm_name_hash (symtab_node node) | |
185 | { | |
c3167b00 JH |
186 | unlink_from_assembler_name_hash (node, false); |
187 | insert_to_assembler_name_hash (node, false); | |
b5493fb2 JH |
188 | } |
189 | ||
1ab24192 | 190 | |
2aae7680 JH |
191 | /* Add node into symbol table. This function is not used directly, but via |
192 | cgraph/varpool node creation routines. */ | |
193 | ||
194 | void | |
195 | symtab_register_node (symtab_node node) | |
196 | { | |
1ab24192 JH |
197 | struct symtab_node_base key; |
198 | symtab_node *slot; | |
199 | ||
2aae7680 JH |
200 | node->symbol.next = symtab_nodes; |
201 | node->symbol.previous = NULL; | |
202 | if (symtab_nodes) | |
203 | symtab_nodes->symbol.previous = node; | |
204 | symtab_nodes = node; | |
205 | ||
1ab24192 JH |
206 | if (!symtab_hash) |
207 | symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL); | |
208 | key.decl = node->symbol.decl; | |
209 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, INSERT); | |
210 | if (*slot == NULL) | |
211 | *slot = node; | |
212 | ||
66379195 | 213 | ipa_empty_ref_list (&node->symbol.ref_list); |
1ab24192 | 214 | |
2aae7680 JH |
215 | node->symbol.order = symtab_order++; |
216 | ||
66379195 JH |
217 | /* Be sure to do this last; C++ FE might create new nodes via |
218 | DECL_ASSEMBLER_NAME langhook! */ | |
c3167b00 | 219 | insert_to_assembler_name_hash (node, false); |
2aae7680 JH |
220 | } |
221 | ||
1ab24192 JH |
222 | /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree |
223 | of inline clones. */ | |
224 | ||
225 | void | |
226 | symtab_insert_node_to_hashtable (symtab_node node) | |
227 | { | |
228 | struct symtab_node_base key; | |
229 | symtab_node *slot; | |
230 | ||
231 | if (!symtab_hash) | |
232 | symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL); | |
233 | key.decl = node->symbol.decl; | |
234 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, INSERT); | |
235 | *slot = node; | |
236 | } | |
237 | ||
2aae7680 JH |
238 | /* Remove node from symbol table. This function is not used directly, but via |
239 | cgraph/varpool node removal routines. */ | |
240 | ||
241 | void | |
242 | symtab_unregister_node (symtab_node node) | |
243 | { | |
1ab24192 | 244 | void **slot; |
2aae7680 | 245 | ipa_remove_all_references (&node->symbol.ref_list); |
5932a4d4 | 246 | ipa_remove_all_referring (&node->symbol.ref_list); |
2aae7680 JH |
247 | |
248 | if (node->symbol.same_comdat_group) | |
249 | { | |
250 | symtab_node prev; | |
251 | for (prev = node->symbol.same_comdat_group; | |
252 | prev->symbol.same_comdat_group != node; | |
253 | prev = prev->symbol.same_comdat_group) | |
254 | ; | |
255 | if (node->symbol.same_comdat_group == prev) | |
256 | prev->symbol.same_comdat_group = NULL; | |
257 | else | |
258 | prev->symbol.same_comdat_group = node->symbol.same_comdat_group; | |
259 | node->symbol.same_comdat_group = NULL; | |
260 | } | |
261 | ||
262 | if (node->symbol.previous) | |
263 | node->symbol.previous->symbol.next = node->symbol.next; | |
264 | else | |
265 | symtab_nodes = node->symbol.next; | |
266 | if (node->symbol.next) | |
267 | node->symbol.next->symbol.previous = node->symbol.previous; | |
268 | node->symbol.next = NULL; | |
269 | node->symbol.previous = NULL; | |
1ab24192 JH |
270 | |
271 | slot = htab_find_slot (symtab_hash, node, NO_INSERT); | |
bbf9ad07 JH |
272 | |
273 | /* During LTO symtab merging we temporarily corrupt decl to symtab node | |
274 | hash. */ | |
275 | gcc_assert ((slot && *slot) || in_lto_p); | |
276 | if (slot && *slot && *slot == node) | |
1ab24192 JH |
277 | { |
278 | symtab_node replacement_node = NULL; | |
5d59b5e1 LC |
279 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
280 | replacement_node = (symtab_node)cgraph_find_replacement_node (cnode); | |
1ab24192 JH |
281 | if (!replacement_node) |
282 | htab_clear_slot (symtab_hash, slot); | |
283 | else | |
284 | *slot = replacement_node; | |
285 | } | |
c3167b00 | 286 | unlink_from_assembler_name_hash (node, false); |
1ab24192 JH |
287 | } |
288 | ||
289 | /* Return symbol table node associated with DECL, if any, | |
290 | and NULL otherwise. */ | |
291 | ||
292 | symtab_node | |
293 | symtab_get_node (const_tree decl) | |
294 | { | |
295 | symtab_node *slot; | |
296 | struct symtab_node_base key; | |
297 | ||
bbf9ad07 JH |
298 | #ifdef ENABLE_CHECKING |
299 | /* Check that we are called for sane type of object - functions | |
300 | and static or external variables. */ | |
1ab24192 JH |
301 | gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL |
302 | || (TREE_CODE (decl) == VAR_DECL | |
303 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) | |
304 | || in_lto_p))); | |
bbf9ad07 | 305 | #endif |
1ab24192 JH |
306 | |
307 | if (!symtab_hash) | |
308 | return NULL; | |
309 | ||
310 | key.decl = CONST_CAST2 (tree, const_tree, decl); | |
311 | ||
312 | slot = (symtab_node *) htab_find_slot (symtab_hash, &key, | |
313 | NO_INSERT); | |
314 | ||
315 | if (slot) | |
316 | return *slot; | |
317 | return NULL; | |
2aae7680 JH |
318 | } |
319 | ||
320 | /* Remove symtab NODE from the symbol table. */ | |
321 | ||
322 | void | |
323 | symtab_remove_node (symtab_node node) | |
324 | { | |
5d59b5e1 LC |
325 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
326 | cgraph_remove_node (cnode); | |
327 | else if (varpool_node *vnode = dyn_cast <varpool_node> (node)) | |
328 | varpool_remove_node (vnode); | |
2aae7680 | 329 | } |
1ab24192 | 330 | |
b5493fb2 | 331 | /* Initalize asm name hash unless. */ |
1ab24192 | 332 | |
b5493fb2 JH |
333 | void |
334 | symtab_initialize_asm_name_hash (void) | |
1ab24192 JH |
335 | { |
336 | symtab_node node; | |
1ab24192 JH |
337 | if (!assembler_name_hash) |
338 | { | |
339 | assembler_name_hash = | |
340 | htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name, | |
341 | NULL); | |
342 | FOR_EACH_SYMBOL (node) | |
c3167b00 | 343 | insert_to_assembler_name_hash (node, false); |
1ab24192 | 344 | } |
b5493fb2 | 345 | } |
1ab24192 | 346 | |
b5493fb2 JH |
347 | /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME. |
348 | Return NULL if there's no such node. */ | |
349 | ||
350 | symtab_node | |
351 | symtab_node_for_asm (const_tree asmname) | |
352 | { | |
353 | symtab_node node; | |
354 | void **slot; | |
355 | ||
356 | symtab_initialize_asm_name_hash (); | |
1ab24192 JH |
357 | slot = htab_find_slot_with_hash (assembler_name_hash, asmname, |
358 | decl_assembler_name_hash (asmname), | |
359 | NO_INSERT); | |
360 | ||
361 | if (slot) | |
362 | { | |
363 | node = (symtab_node) *slot; | |
364 | return node; | |
365 | } | |
366 | return NULL; | |
367 | } | |
368 | ||
369 | /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */ | |
370 | ||
371 | void | |
372 | change_decl_assembler_name (tree decl, tree name) | |
373 | { | |
374 | symtab_node node = NULL; | |
375 | ||
376 | /* We can have user ASM names on things, like global register variables, that | |
377 | are not in the symbol table. */ | |
378 | if ((TREE_CODE (decl) == VAR_DECL | |
379 | && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
380 | || TREE_CODE (decl) == FUNCTION_DECL) | |
381 | node = symtab_get_node (decl); | |
382 | if (!DECL_ASSEMBLER_NAME_SET_P (decl)) | |
383 | { | |
384 | SET_DECL_ASSEMBLER_NAME (decl, name); | |
385 | if (node) | |
c3167b00 | 386 | insert_to_assembler_name_hash (node, true); |
1ab24192 JH |
387 | } |
388 | else | |
389 | { | |
390 | if (name == DECL_ASSEMBLER_NAME (decl)) | |
391 | return; | |
392 | ||
393 | if (node) | |
c3167b00 | 394 | unlink_from_assembler_name_hash (node, true); |
1ab24192 JH |
395 | if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) |
396 | && DECL_RTL_SET_P (decl)) | |
397 | warning (0, "%D renamed after being referenced in assembly", decl); | |
398 | ||
399 | SET_DECL_ASSEMBLER_NAME (decl, name); | |
400 | if (node) | |
c3167b00 | 401 | insert_to_assembler_name_hash (node, true); |
1ab24192 JH |
402 | } |
403 | } | |
404 | ||
65d630d4 JH |
405 | /* Add NEW_ to the same comdat group that OLD is in. */ |
406 | ||
407 | void | |
408 | symtab_add_to_same_comdat_group (symtab_node new_node, | |
409 | symtab_node old_node) | |
410 | { | |
411 | gcc_assert (DECL_ONE_ONLY (old_node->symbol.decl)); | |
412 | gcc_assert (!new_node->symbol.same_comdat_group); | |
413 | gcc_assert (new_node != old_node); | |
414 | ||
415 | DECL_COMDAT_GROUP (new_node->symbol.decl) = DECL_COMDAT_GROUP (old_node->symbol.decl); | |
416 | new_node->symbol.same_comdat_group = old_node; | |
417 | if (!old_node->symbol.same_comdat_group) | |
418 | old_node->symbol.same_comdat_group = new_node; | |
419 | else | |
420 | { | |
421 | symtab_node n; | |
422 | for (n = old_node->symbol.same_comdat_group; | |
423 | n->symbol.same_comdat_group != old_node; | |
424 | n = n->symbol.same_comdat_group) | |
425 | ; | |
426 | n->symbol.same_comdat_group = new_node; | |
427 | } | |
428 | } | |
429 | ||
430 | /* Dissolve the same_comdat_group list in which NODE resides. */ | |
431 | ||
432 | void | |
433 | symtab_dissolve_same_comdat_group_list (symtab_node node) | |
434 | { | |
435 | symtab_node n = node, next; | |
436 | ||
437 | if (!node->symbol.same_comdat_group) | |
438 | return; | |
439 | do | |
440 | { | |
441 | next = n->symbol.same_comdat_group; | |
442 | n->symbol.same_comdat_group = NULL; | |
443 | n = next; | |
444 | } | |
445 | while (n != node); | |
446 | } | |
447 | ||
8f940ee6 JH |
448 | /* Return printable assembler name of NODE. |
449 | This function is used only for debugging. When assembler name | |
450 | is unknown go with identifier name. */ | |
451 | ||
452 | const char * | |
453 | symtab_node_asm_name (symtab_node node) | |
454 | { | |
455 | if (!DECL_ASSEMBLER_NAME_SET_P (node->symbol.decl)) | |
456 | return lang_hooks.decl_printable_name (node->symbol.decl, 2); | |
457 | return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->symbol.decl)); | |
458 | } | |
459 | ||
460 | /* Return printable identifier name. */ | |
461 | ||
462 | const char * | |
463 | symtab_node_name (symtab_node node) | |
464 | { | |
465 | return lang_hooks.decl_printable_name (node->symbol.decl, 2); | |
466 | } | |
467 | ||
468 | static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; | |
469 | ||
470 | /* Dump base fields of symtab nodes. Not to be used directly. */ | |
471 | ||
472 | void | |
473 | dump_symtab_base (FILE *f, symtab_node node) | |
474 | { | |
475 | static const char * const visibility_types[] = { | |
476 | "default", "protected", "hidden", "internal" | |
477 | }; | |
478 | ||
479 | fprintf (f, "%s/%i (%s)", | |
480 | symtab_node_asm_name (node), | |
481 | node->symbol.order, | |
482 | symtab_node_name (node)); | |
483 | dump_addr (f, " @", (void *)node); | |
e70670cf JH |
484 | fprintf (f, "\n Type: %s", symtab_type_names[node->symbol.type]); |
485 | ||
486 | if (node->symbol.definition) | |
487 | fprintf (f, " definition"); | |
488 | if (node->symbol.analyzed) | |
489 | fprintf (f, " analyzed"); | |
490 | if (node->symbol.alias) | |
491 | fprintf (f, " alias"); | |
08346abd JH |
492 | if (node->symbol.weakref) |
493 | fprintf (f, " weakref"); | |
40a7fe1e JH |
494 | if (node->symbol.cpp_implicit_alias) |
495 | fprintf (f, " cpp_implicit_alias"); | |
496 | if (node->symbol.alias_target) | |
497 | fprintf (f, " target:%s", | |
498 | DECL_P (node->symbol.alias_target) | |
499 | ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME | |
500 | (node->symbol.alias_target)) | |
501 | : IDENTIFIER_POINTER (node->symbol.alias_target)); | |
e70670cf | 502 | fprintf (f, "\n Visibility:"); |
8f940ee6 JH |
503 | if (node->symbol.in_other_partition) |
504 | fprintf (f, " in_other_partition"); | |
505 | if (node->symbol.used_from_other_partition) | |
506 | fprintf (f, " used_from_other_partition"); | |
ead84f73 JH |
507 | if (node->symbol.force_output) |
508 | fprintf (f, " force_output"); | |
edb983b2 JH |
509 | if (node->symbol.forced_by_abi) |
510 | fprintf (f, " forced_by_abi"); | |
e5b962d0 JH |
511 | if (node->symbol.externally_visible) |
512 | fprintf (f, " externally_visible"); | |
8f940ee6 JH |
513 | if (node->symbol.resolution != LDPR_UNKNOWN) |
514 | fprintf (f, " %s", | |
515 | ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]); | |
516 | if (TREE_ASM_WRITTEN (node->symbol.decl)) | |
517 | fprintf (f, " asm_written"); | |
518 | if (DECL_EXTERNAL (node->symbol.decl)) | |
519 | fprintf (f, " external"); | |
520 | if (TREE_PUBLIC (node->symbol.decl)) | |
521 | fprintf (f, " public"); | |
522 | if (DECL_COMMON (node->symbol.decl)) | |
523 | fprintf (f, " common"); | |
524 | if (DECL_WEAK (node->symbol.decl)) | |
525 | fprintf (f, " weak"); | |
526 | if (DECL_DLLIMPORT_P (node->symbol.decl)) | |
527 | fprintf (f, " dll_import"); | |
528 | if (DECL_COMDAT (node->symbol.decl)) | |
529 | fprintf (f, " comdat"); | |
530 | if (DECL_COMDAT_GROUP (node->symbol.decl)) | |
531 | fprintf (f, " comdat_group:%s", | |
532 | IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->symbol.decl))); | |
533 | if (DECL_ONE_ONLY (node->symbol.decl)) | |
534 | fprintf (f, " one_only"); | |
535 | if (DECL_SECTION_NAME (node->symbol.decl)) | |
536 | fprintf (f, " section_name:%s", | |
f68c0487 | 537 | TREE_STRING_POINTER (DECL_SECTION_NAME (node->symbol.decl))); |
8f940ee6 JH |
538 | if (DECL_VISIBILITY_SPECIFIED (node->symbol.decl)) |
539 | fprintf (f, " visibility_specified"); | |
540 | if (DECL_VISIBILITY (node->symbol.decl)) | |
541 | fprintf (f, " visibility:%s", | |
542 | visibility_types [DECL_VISIBILITY (node->symbol.decl)]); | |
543 | if (DECL_VIRTUAL_P (node->symbol.decl)) | |
544 | fprintf (f, " virtual"); | |
545 | if (DECL_ARTIFICIAL (node->symbol.decl)) | |
546 | fprintf (f, " artificial"); | |
838ff415 JH |
547 | if (TREE_CODE (node->symbol.decl) == FUNCTION_DECL) |
548 | { | |
549 | if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl)) | |
550 | fprintf (f, " constructor"); | |
551 | if (DECL_STATIC_DESTRUCTOR (node->symbol.decl)) | |
552 | fprintf (f, " destructor"); | |
553 | } | |
8f940ee6 JH |
554 | fprintf (f, "\n"); |
555 | ||
556 | if (node->symbol.same_comdat_group) | |
557 | fprintf (f, " Same comdat group as: %s/%i\n", | |
558 | symtab_node_asm_name (node->symbol.same_comdat_group), | |
559 | node->symbol.same_comdat_group->symbol.order); | |
560 | if (node->symbol.next_sharing_asm_name) | |
561 | fprintf (f, " next sharing asm name: %i\n", | |
fe0bd630 | 562 | node->symbol.next_sharing_asm_name->symbol.order); |
8f940ee6 JH |
563 | if (node->symbol.previous_sharing_asm_name) |
564 | fprintf (f, " previous sharing asm name: %i\n", | |
fe0bd630 | 565 | node->symbol.previous_sharing_asm_name->symbol.order); |
8f940ee6 JH |
566 | |
567 | if (node->symbol.address_taken) | |
fe0bd630 | 568 | fprintf (f, " Address is taken.\n"); |
66058468 JH |
569 | if (node->symbol.aux) |
570 | { | |
571 | fprintf (f, " Aux:"); | |
572 | dump_addr (f, " @", (void *)node->symbol.aux); | |
573 | } | |
8f940ee6 JH |
574 | |
575 | fprintf (f, " References: "); | |
576 | ipa_dump_references (f, &node->symbol.ref_list); | |
5932a4d4 JH |
577 | fprintf (f, " Referring: "); |
578 | ipa_dump_referring (f, &node->symbol.ref_list); | |
b5493fb2 JH |
579 | if (node->symbol.lto_file_data) |
580 | fprintf (f, " Read from file: %s\n", | |
581 | node->symbol.lto_file_data->file_name); | |
8f940ee6 JH |
582 | } |
583 | ||
584 | /* Dump symtab node. */ | |
585 | ||
586 | void | |
587 | dump_symtab_node (FILE *f, symtab_node node) | |
588 | { | |
5d59b5e1 LC |
589 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
590 | dump_cgraph_node (f, cnode); | |
591 | else if (varpool_node *vnode = dyn_cast <varpool_node> (node)) | |
592 | dump_varpool_node (f, vnode); | |
8f940ee6 JH |
593 | } |
594 | ||
595 | /* Dump symbol table. */ | |
596 | ||
597 | void | |
598 | dump_symtab (FILE *f) | |
599 | { | |
600 | symtab_node node; | |
601 | fprintf (f, "Symbol table:\n\n"); | |
602 | FOR_EACH_SYMBOL (node) | |
603 | dump_symtab_node (f, node); | |
604 | } | |
605 | ||
606 | /* Dump symtab node NODE to stderr. */ | |
607 | ||
608 | DEBUG_FUNCTION void | |
609 | debug_symtab_node (symtab_node node) | |
610 | { | |
611 | dump_symtab_node (stderr, node); | |
612 | } | |
613 | ||
614 | /* Dump symbol table to stderr. */ | |
615 | ||
616 | DEBUG_FUNCTION void | |
617 | debug_symtab (void) | |
618 | { | |
619 | dump_symtab (stderr); | |
620 | } | |
621 | ||
474ffc72 JH |
622 | /* Verify common part of symtab nodes. */ |
623 | ||
624 | DEBUG_FUNCTION bool | |
625 | verify_symtab_base (symtab_node node) | |
626 | { | |
627 | bool error_found = false; | |
628 | symtab_node hashed_node; | |
629 | ||
5d59b5e1 | 630 | if (is_a <cgraph_node> (node)) |
474ffc72 JH |
631 | { |
632 | if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL) | |
633 | { | |
634 | error ("function symbol is not function"); | |
635 | error_found = true; | |
636 | } | |
637 | } | |
5d59b5e1 | 638 | else if (is_a <varpool_node> (node)) |
474ffc72 JH |
639 | { |
640 | if (TREE_CODE (node->symbol.decl) != VAR_DECL) | |
641 | { | |
642 | error ("variable symbol is not variable"); | |
643 | error_found = true; | |
644 | } | |
645 | } | |
646 | else | |
647 | { | |
648 | error ("node has unknown type"); | |
649 | error_found = true; | |
650 | } | |
651 | ||
ca0f62a8 | 652 | if (cgraph_state != CGRAPH_LTO_STREAMING) |
474ffc72 | 653 | { |
ca0f62a8 JH |
654 | hashed_node = symtab_get_node (node->symbol.decl); |
655 | if (!hashed_node) | |
656 | { | |
657 | error ("node not found in symtab decl hashtable"); | |
658 | error_found = true; | |
659 | } | |
e5b962d0 JH |
660 | if (hashed_node != node |
661 | && (!is_a <cgraph_node> (node) | |
662 | || !dyn_cast <cgraph_node> (node)->clone_of | |
663 | || dyn_cast <cgraph_node> (node)->clone_of->symbol.decl | |
664 | != node->symbol.decl)) | |
665 | { | |
666 | error ("node differs from symtab decl hashtable"); | |
667 | error_found = true; | |
668 | } | |
474ffc72 JH |
669 | } |
670 | if (assembler_name_hash) | |
671 | { | |
672 | hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->symbol.decl)); | |
673 | if (hashed_node && hashed_node->symbol.previous_sharing_asm_name) | |
674 | { | |
675 | error ("assembler name hash list corrupted"); | |
676 | error_found = true; | |
677 | } | |
678 | while (hashed_node) | |
679 | { | |
680 | if (hashed_node == node) | |
681 | break; | |
682 | hashed_node = hashed_node->symbol.next_sharing_asm_name; | |
683 | } | |
b5493fb2 | 684 | if (!hashed_node |
5d59b5e1 LC |
685 | && !(is_a <varpool_node> (node) |
686 | || DECL_HARD_REGISTER (node->symbol.decl))) | |
474ffc72 JH |
687 | { |
688 | error ("node not found in symtab assembler name hash"); | |
689 | error_found = true; | |
690 | } | |
691 | } | |
692 | if (node->symbol.previous_sharing_asm_name | |
693 | && node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node) | |
694 | { | |
695 | error ("double linked list of assembler names corrupted"); | |
e70670cf JH |
696 | error_found = true; |
697 | } | |
698 | if (node->symbol.analyzed && !node->symbol.definition) | |
699 | { | |
700 | error ("node is analyzed byt it is not a definition"); | |
701 | error_found = true; | |
474ffc72 | 702 | } |
40a7fe1e JH |
703 | if (node->symbol.cpp_implicit_alias && !node->symbol.alias) |
704 | { | |
705 | error ("node is alias but not implicit alias"); | |
706 | error_found = true; | |
707 | } | |
708 | if (node->symbol.alias && !node->symbol.definition | |
08346abd | 709 | && !node->symbol.weakref) |
40a7fe1e JH |
710 | { |
711 | error ("node is alias but not definition"); | |
712 | error_found = true; | |
713 | } | |
08346abd JH |
714 | if (node->symbol.weakref && !node->symbol.alias) |
715 | { | |
716 | error ("node is weakref but not an alias"); | |
717 | error_found = true; | |
718 | } | |
474ffc72 JH |
719 | if (node->symbol.same_comdat_group) |
720 | { | |
721 | symtab_node n = node->symbol.same_comdat_group; | |
722 | ||
723 | if (!DECL_ONE_ONLY (n->symbol.decl)) | |
724 | { | |
725 | error ("non-DECL_ONE_ONLY node in a same_comdat_group list"); | |
726 | error_found = true; | |
727 | } | |
728 | if (n->symbol.type != node->symbol.type) | |
729 | { | |
730 | error ("mixing different types of symbol in same comdat groups is not supported"); | |
731 | error_found = true; | |
732 | } | |
733 | if (n == node) | |
734 | { | |
735 | error ("node is alone in a comdat group"); | |
736 | error_found = true; | |
737 | } | |
738 | do | |
739 | { | |
740 | if (!n->symbol.same_comdat_group) | |
741 | { | |
742 | error ("same_comdat_group is not a circular list"); | |
743 | error_found = true; | |
744 | break; | |
745 | } | |
746 | n = n->symbol.same_comdat_group; | |
747 | } | |
748 | while (n != node); | |
749 | } | |
750 | return error_found; | |
751 | } | |
752 | ||
753 | /* Verify consistency of NODE. */ | |
754 | ||
755 | DEBUG_FUNCTION void | |
756 | verify_symtab_node (symtab_node node) | |
757 | { | |
758 | if (seen_error ()) | |
759 | return; | |
760 | ||
761 | timevar_push (TV_CGRAPH_VERIFY); | |
5d59b5e1 LC |
762 | if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) |
763 | verify_cgraph_node (cnode); | |
474ffc72 JH |
764 | else |
765 | if (verify_symtab_base (node)) | |
766 | { | |
767 | dump_symtab_node (stderr, node); | |
768 | internal_error ("verify_symtab_node failed"); | |
769 | } | |
770 | timevar_pop (TV_CGRAPH_VERIFY); | |
771 | } | |
772 | ||
773 | /* Verify symbol table for internal consistency. */ | |
774 | ||
775 | DEBUG_FUNCTION void | |
776 | verify_symtab (void) | |
777 | { | |
778 | symtab_node node; | |
779 | FOR_EACH_SYMBOL (node) | |
780 | verify_symtab_node (node); | |
781 | } | |
782 | ||
65d630d4 JH |
783 | /* Return true when RESOLUTION indicate that linker will use |
784 | the symbol from non-LTO object files. */ | |
785 | ||
786 | bool | |
787 | resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution) | |
788 | { | |
789 | return (resolution == LDPR_PREVAILING_DEF | |
790 | || resolution == LDPR_PREEMPTED_REG | |
791 | || resolution == LDPR_RESOLVED_EXEC | |
792 | || resolution == LDPR_RESOLVED_DYN); | |
793 | } | |
794 | ||
795 | /* Return true when NODE is known to be used from other (non-LTO) object file. | |
796 | Known only when doing LTO via linker plugin. */ | |
797 | ||
798 | bool | |
799 | symtab_used_from_object_file_p (symtab_node node) | |
800 | { | |
801 | if (!TREE_PUBLIC (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl)) | |
802 | return false; | |
803 | if (resolution_used_from_other_file_p (node->symbol.resolution)) | |
804 | return true; | |
805 | return false; | |
806 | } | |
807 | ||
808 | /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early, | |
809 | but other code such as notice_global_symbol generates rtl. */ | |
40a7fe1e | 810 | |
65d630d4 JH |
811 | void |
812 | symtab_make_decl_local (tree decl) | |
813 | { | |
814 | rtx rtl, symbol; | |
815 | ||
816 | if (TREE_CODE (decl) == VAR_DECL) | |
817 | DECL_COMMON (decl) = 0; | |
818 | else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); | |
819 | ||
820 | if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl)) | |
821 | { | |
65d630d4 JH |
822 | DECL_SECTION_NAME (decl) = 0; |
823 | DECL_COMDAT (decl) = 0; | |
824 | } | |
825 | DECL_COMDAT_GROUP (decl) = 0; | |
826 | DECL_WEAK (decl) = 0; | |
827 | DECL_EXTERNAL (decl) = 0; | |
b5493fb2 JH |
828 | DECL_VISIBILITY_SPECIFIED (decl) = 0; |
829 | DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; | |
65d630d4 JH |
830 | TREE_PUBLIC (decl) = 0; |
831 | if (!DECL_RTL_SET_P (decl)) | |
832 | return; | |
833 | ||
834 | /* Update rtl flags. */ | |
835 | make_decl_rtl (decl); | |
836 | ||
837 | rtl = DECL_RTL (decl); | |
838 | if (!MEM_P (rtl)) | |
839 | return; | |
840 | ||
841 | symbol = XEXP (rtl, 0); | |
842 | if (GET_CODE (symbol) != SYMBOL_REF) | |
843 | return; | |
844 | ||
845 | SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl); | |
846 | } | |
e70670cf | 847 | |
40a7fe1e JH |
848 | /* Return availability of NODE. */ |
849 | ||
850 | enum availability | |
851 | symtab_node_availability (symtab_node node) | |
852 | { | |
853 | if (is_a <cgraph_node> (node)) | |
854 | return cgraph_function_body_availability (cgraph (node)); | |
855 | else | |
856 | return cgraph_variable_initializer_availability (varpool (node)); | |
857 | } | |
858 | ||
e70670cf JH |
859 | /* Given NODE, walk the alias chain to return the symbol NODE is alias of. |
860 | If NODE is not an alias, return NODE. | |
861 | When AVAILABILITY is non-NULL, get minimal availability in the chain. */ | |
862 | ||
863 | symtab_node | |
864 | symtab_alias_ultimate_target (symtab_node node, enum availability *availability) | |
865 | { | |
aaae719d JH |
866 | bool weakref_p = false; |
867 | ||
868 | if (!node->symbol.alias) | |
869 | { | |
870 | if (availability) | |
871 | *availability = symtab_node_availability (node); | |
872 | return node; | |
873 | } | |
874 | ||
875 | /* To determine visibility of the target, we follow ELF semantic of aliases. | |
876 | Here alias is an alternative assembler name of a given definition. Its | |
877 | availablity prevails the availablity of its target (i.e. static alias of | |
878 | weak definition is available. | |
879 | ||
880 | Weakref is a different animal (and not part of ELF per se). It is just | |
881 | alternative name of a given symbol used within one complation unit | |
882 | and is translated prior hitting the object file. It inherits the | |
883 | visibility of its target (i.e. weakref of non-overwritable definition | |
884 | is non-overwritable, while weakref of weak definition is weak). | |
885 | ||
886 | If we ever get into supporting targets with different semantics, a target | |
887 | hook will be needed here. */ | |
888 | ||
e70670cf | 889 | if (availability) |
aaae719d | 890 | { |
08346abd | 891 | weakref_p = node->symbol.weakref; |
aaae719d JH |
892 | if (!weakref_p) |
893 | *availability = symtab_node_availability (node); | |
894 | else | |
895 | *availability = AVAIL_LOCAL; | |
896 | } | |
e70670cf JH |
897 | while (node) |
898 | { | |
899 | if (node->symbol.alias && node->symbol.analyzed) | |
900 | node = symtab_alias_target (node); | |
901 | else | |
aaae719d JH |
902 | { |
903 | if (!availability) | |
904 | ; | |
905 | else if (node->symbol.analyzed) | |
906 | { | |
907 | if (weakref_p) | |
908 | { | |
909 | enum availability a = symtab_node_availability (node); | |
910 | if (a < *availability) | |
911 | *availability = a; | |
912 | } | |
913 | } | |
914 | else | |
915 | *availability = AVAIL_NOT_AVAILABLE; | |
916 | return node; | |
917 | } | |
918 | if (node && availability && weakref_p) | |
e70670cf | 919 | { |
40a7fe1e | 920 | enum availability a = symtab_node_availability (node); |
e70670cf JH |
921 | if (a < *availability) |
922 | *availability = a; | |
08346abd | 923 | weakref_p = node->symbol.weakref; |
e70670cf JH |
924 | } |
925 | } | |
926 | if (availability) | |
927 | *availability = AVAIL_NOT_AVAILABLE; | |
928 | return NULL; | |
929 | } | |
40a7fe1e JH |
930 | |
931 | /* C++ FE sometimes change linkage flags after producing same body aliases. | |
932 | ||
933 | FIXME: C++ produce implicit aliases for virtual functions and vtables that | |
934 | are obviously equivalent. The way it is doing so is however somewhat | |
935 | kludgy and interferes with the visibility code. As a result we need to | |
936 | copy the visibility from the target to get things right. */ | |
937 | ||
938 | void | |
939 | fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target) | |
940 | { | |
941 | if (is_a <cgraph_node> (node)) | |
942 | { | |
943 | DECL_DECLARED_INLINE_P (node->symbol.decl) | |
944 | = DECL_DECLARED_INLINE_P (target->symbol.decl); | |
945 | DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl) | |
946 | = DECL_DISREGARD_INLINE_LIMITS (target->symbol.decl); | |
947 | } | |
948 | /* FIXME: It is not really clear why those flags should not be copied for | |
949 | functions, too. */ | |
950 | else | |
951 | { | |
952 | DECL_WEAK (node->symbol.decl) = DECL_WEAK (target->symbol.decl); | |
953 | DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl); | |
954 | DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (target->symbol.decl); | |
955 | } | |
956 | DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (target->symbol.decl); | |
957 | if (TREE_PUBLIC (node->symbol.decl)) | |
958 | { | |
959 | DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl); | |
960 | DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (target->symbol.decl); | |
961 | DECL_COMDAT_GROUP (node->symbol.decl) | |
962 | = DECL_COMDAT_GROUP (target->symbol.decl); | |
963 | if (DECL_ONE_ONLY (target->symbol.decl) | |
964 | && !node->symbol.same_comdat_group) | |
965 | symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target); | |
966 | } | |
967 | node->symbol.externally_visible = target->symbol.externally_visible; | |
968 | } | |
969 | ||
970 | /* Add reference recording that NODE is alias of TARGET. | |
971 | The function can fail in the case of aliasing cycles; in this case | |
972 | it returns false. */ | |
973 | ||
974 | bool | |
975 | symtab_resolve_alias (symtab_node node, symtab_node target) | |
976 | { | |
977 | symtab_node n; | |
978 | ||
979 | gcc_assert (!node->symbol.analyzed | |
980 | && !vec_safe_length (node->symbol.ref_list.references)); | |
981 | ||
982 | /* Never let cycles to creep into the symbol table alias references; | |
983 | those will make alias walkers to be infinite. */ | |
984 | for (n = target; n && n->symbol.alias; | |
985 | n = n->symbol.analyzed ? symtab_alias_target (n) : NULL) | |
986 | if (n == node) | |
987 | { | |
988 | if (is_a <cgraph_node> (node)) | |
989 | error ("function %q+D part of alias cycle", node->symbol.decl); | |
990 | else if (is_a <varpool_node> (node)) | |
991 | error ("variable %q+D part of alias cycle", node->symbol.decl); | |
992 | else | |
993 | gcc_unreachable (); | |
994 | node->symbol.alias = false; | |
995 | return false; | |
996 | } | |
997 | ||
998 | /* "analyze" the node - i.e. mark the reference. */ | |
999 | node->symbol.definition = true; | |
1000 | node->symbol.alias = true; | |
1001 | node->symbol.analyzed = true; | |
1002 | ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); | |
1003 | ||
1004 | /* Alias targets become reudndant after alias is resolved into an reference. | |
1005 | We do not want to keep it around or we would have to mind updating them | |
1006 | when renaming symbols. */ | |
1007 | node->symbol.alias_target = NULL; | |
40a7fe1e JH |
1008 | |
1009 | if (node->symbol.cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION) | |
1010 | fixup_same_cpp_alias_visibility (node, target); | |
1011 | ||
1012 | /* If alias has address taken, so does the target. */ | |
1013 | if (node->symbol.address_taken) | |
1014 | symtab_alias_ultimate_target (target, NULL)->symbol.address_taken = true; | |
1015 | return true; | |
1016 | } | |
1ab24192 | 1017 | #include "gt-symtab.h" |