2 Copyright (C) 2012 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
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
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
26 #include "tree-inline.h"
27 #include "langhooks.h"
31 #include "diagnostic.h"
34 /* Hash table used to convert declarations into nodes. */
35 static GTY((param_is (union symtab_node_def
))) htab_t symtab_hash
;
36 /* Hash table used to convert assembler names into nodes. */
37 static GTY((param_is (union symtab_node_def
))) htab_t assembler_name_hash
;
39 /* Linked list of symbol table nodes. */
40 symtab_node symtab_nodes
;
42 /* The order index of the next symtab node to be created. This is
43 used so that we can sort the cgraph nodes in order by when we saw
44 them, to support -fno-toplevel-reorder. */
47 /* Returns a hash code for P. */
50 hash_node (const void *p
)
52 const_symtab_node n
= (const_symtab_node
) p
;
53 return (hashval_t
) DECL_UID (n
->symbol
.decl
);
57 /* Returns nonzero if P1 and P2 are equal. */
60 eq_node (const void *p1
, const void *p2
)
62 const_symtab_node n1
= (const_symtab_node
) p1
;
63 const_symtab_node n2
= (const_symtab_node
) p2
;
64 return DECL_UID (n1
->symbol
.decl
) == DECL_UID (n2
->symbol
.decl
);
67 /* Returns a hash code for P. */
70 hash_node_by_assembler_name (const void *p
)
72 const_symtab_node n
= (const_symtab_node
) p
;
73 return (hashval_t
) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n
->symbol
.decl
));
76 /* Returns nonzero if P1 and P2 are equal. */
79 eq_assembler_name (const void *p1
, const void *p2
)
81 const_symtab_node n1
= (const_symtab_node
) p1
;
82 const_tree name
= (const_tree
)p2
;
83 return (decl_assembler_name_equal (n1
->symbol
.decl
, name
));
86 /* Insert NODE to assembler name hash. */
89 insert_to_assembler_name_hash (symtab_node node
)
91 gcc_checking_assert (!node
->symbol
.previous_sharing_asm_name
92 && !node
->symbol
.next_sharing_asm_name
);
93 if (assembler_name_hash
)
96 tree name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
98 aslot
= htab_find_slot_with_hash (assembler_name_hash
, name
,
99 decl_assembler_name_hash (name
),
101 gcc_assert (*aslot
!= node
);
102 node
->symbol
.next_sharing_asm_name
= (symtab_node
)*aslot
;
104 ((symtab_node
)*aslot
)->symbol
.previous_sharing_asm_name
= node
;
110 /* Remove NODE from assembler name hash. */
113 unlink_from_assembler_name_hash (symtab_node node
)
115 if (assembler_name_hash
)
117 if (node
->symbol
.next_sharing_asm_name
)
118 node
->symbol
.next_sharing_asm_name
->symbol
.previous_sharing_asm_name
119 = node
->symbol
.previous_sharing_asm_name
;
120 if (node
->symbol
.previous_sharing_asm_name
)
122 node
->symbol
.previous_sharing_asm_name
->symbol
.next_sharing_asm_name
123 = node
->symbol
.next_sharing_asm_name
;
127 tree name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
129 slot
= htab_find_slot_with_hash (assembler_name_hash
, name
,
130 decl_assembler_name_hash (name
),
132 gcc_assert (*slot
== node
);
133 if (!node
->symbol
.next_sharing_asm_name
)
134 htab_clear_slot (assembler_name_hash
, slot
);
136 *slot
= node
->symbol
.next_sharing_asm_name
;
142 /* Add node into symbol table. This function is not used directly, but via
143 cgraph/varpool node creation routines. */
146 symtab_register_node (symtab_node node
)
148 struct symtab_node_base key
;
151 node
->symbol
.next
= symtab_nodes
;
152 node
->symbol
.previous
= NULL
;
154 symtab_nodes
->symbol
.previous
= node
;
158 symtab_hash
= htab_create_ggc (10, hash_node
, eq_node
, NULL
);
159 key
.decl
= node
->symbol
.decl
;
160 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
, INSERT
);
164 insert_to_assembler_name_hash (node
);
166 node
->symbol
.order
= symtab_order
++;
168 ipa_empty_ref_list (&node
->symbol
.ref_list
);
171 /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree
175 symtab_insert_node_to_hashtable (symtab_node node
)
177 struct symtab_node_base key
;
181 symtab_hash
= htab_create_ggc (10, hash_node
, eq_node
, NULL
);
182 key
.decl
= node
->symbol
.decl
;
183 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
, INSERT
);
187 /* Remove node from symbol table. This function is not used directly, but via
188 cgraph/varpool node removal routines. */
191 symtab_unregister_node (symtab_node node
)
194 ipa_remove_all_references (&node
->symbol
.ref_list
);
195 ipa_remove_all_referring (&node
->symbol
.ref_list
);
197 if (node
->symbol
.same_comdat_group
)
200 for (prev
= node
->symbol
.same_comdat_group
;
201 prev
->symbol
.same_comdat_group
!= node
;
202 prev
= prev
->symbol
.same_comdat_group
)
204 if (node
->symbol
.same_comdat_group
== prev
)
205 prev
->symbol
.same_comdat_group
= NULL
;
207 prev
->symbol
.same_comdat_group
= node
->symbol
.same_comdat_group
;
208 node
->symbol
.same_comdat_group
= NULL
;
211 if (node
->symbol
.previous
)
212 node
->symbol
.previous
->symbol
.next
= node
->symbol
.next
;
214 symtab_nodes
= node
->symbol
.next
;
215 if (node
->symbol
.next
)
216 node
->symbol
.next
->symbol
.previous
= node
->symbol
.previous
;
217 node
->symbol
.next
= NULL
;
218 node
->symbol
.previous
= NULL
;
220 slot
= htab_find_slot (symtab_hash
, node
, NO_INSERT
);
223 symtab_node replacement_node
= NULL
;
224 if (symtab_function_p (node
))
225 replacement_node
= (symtab_node
)cgraph_find_replacement_node (cgraph (node
));
226 if (!replacement_node
)
227 htab_clear_slot (symtab_hash
, slot
);
229 *slot
= replacement_node
;
231 unlink_from_assembler_name_hash (node
);
234 /* Return symbol table node associated with DECL, if any,
235 and NULL otherwise. */
238 symtab_get_node (const_tree decl
)
241 struct symtab_node_base key
;
243 gcc_checking_assert (TREE_CODE (decl
) == FUNCTION_DECL
244 || (TREE_CODE (decl
) == VAR_DECL
245 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)
251 key
.decl
= CONST_CAST2 (tree
, const_tree
, decl
);
253 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
,
261 /* Remove symtab NODE from the symbol table. */
264 symtab_remove_node (symtab_node node
)
266 if (symtab_function_p (node
))
267 cgraph_remove_node (cgraph (node
));
268 else if (symtab_variable_p (node
))
269 varpool_remove_node (varpool (node
));
272 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
273 Return NULL if there's no such node. */
276 symtab_node_for_asm (const_tree asmname
)
281 if (!assembler_name_hash
)
283 assembler_name_hash
=
284 htab_create_ggc (10, hash_node_by_assembler_name
, eq_assembler_name
,
286 FOR_EACH_SYMBOL (node
)
287 insert_to_assembler_name_hash (node
);
290 slot
= htab_find_slot_with_hash (assembler_name_hash
, asmname
,
291 decl_assembler_name_hash (asmname
),
296 node
= (symtab_node
) *slot
;
302 /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
305 change_decl_assembler_name (tree decl
, tree name
)
307 symtab_node node
= NULL
;
309 /* We can have user ASM names on things, like global register variables, that
310 are not in the symbol table. */
311 if ((TREE_CODE (decl
) == VAR_DECL
312 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
313 || TREE_CODE (decl
) == FUNCTION_DECL
)
314 node
= symtab_get_node (decl
);
315 if (!DECL_ASSEMBLER_NAME_SET_P (decl
))
317 SET_DECL_ASSEMBLER_NAME (decl
, name
);
319 insert_to_assembler_name_hash (node
);
323 if (name
== DECL_ASSEMBLER_NAME (decl
))
327 unlink_from_assembler_name_hash (node
);
328 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
))
329 && DECL_RTL_SET_P (decl
))
330 warning (0, "%D renamed after being referenced in assembly", decl
);
332 SET_DECL_ASSEMBLER_NAME (decl
, name
);
334 insert_to_assembler_name_hash (node
);
338 /* Return printable assembler name of NODE.
339 This function is used only for debugging. When assembler name
340 is unknown go with identifier name. */
343 symtab_node_asm_name (symtab_node node
)
345 if (!DECL_ASSEMBLER_NAME_SET_P (node
->symbol
.decl
))
346 return lang_hooks
.decl_printable_name (node
->symbol
.decl
, 2);
347 return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node
->symbol
.decl
));
350 /* Return printable identifier name. */
353 symtab_node_name (symtab_node node
)
355 return lang_hooks
.decl_printable_name (node
->symbol
.decl
, 2);
358 static const char * const symtab_type_names
[] = {"symbol", "function", "variable"};
360 /* Dump base fields of symtab nodes. Not to be used directly. */
363 dump_symtab_base (FILE *f
, symtab_node node
)
365 static const char * const visibility_types
[] = {
366 "default", "protected", "hidden", "internal"
369 fprintf (f
, "%s/%i (%s)",
370 symtab_node_asm_name (node
),
372 symtab_node_name (node
));
373 dump_addr (f
, " @", (void *)node
);
374 fprintf (f
, "\n Type: %s\n", symtab_type_names
[node
->symbol
.type
]);
375 fprintf (f
, " Visibility:");
377 if (node
->symbol
.in_other_partition
)
378 fprintf (f
, " in_other_partition");
379 if (node
->symbol
.used_from_other_partition
)
380 fprintf (f
, " used_from_other_partition");
381 if (node
->symbol
.force_output
)
382 fprintf (f
, " force_output");
383 if (node
->symbol
.resolution
!= LDPR_UNKNOWN
)
385 ld_plugin_symbol_resolution_names
[(int)node
->symbol
.resolution
]);
386 if (TREE_ASM_WRITTEN (node
->symbol
.decl
))
387 fprintf (f
, " asm_written");
388 if (DECL_EXTERNAL (node
->symbol
.decl
))
389 fprintf (f
, " external");
390 if (TREE_PUBLIC (node
->symbol
.decl
))
391 fprintf (f
, " public");
392 if (DECL_COMMON (node
->symbol
.decl
))
393 fprintf (f
, " common");
394 if (DECL_WEAK (node
->symbol
.decl
))
395 fprintf (f
, " weak");
396 if (DECL_DLLIMPORT_P (node
->symbol
.decl
))
397 fprintf (f
, " dll_import");
398 if (DECL_COMDAT (node
->symbol
.decl
))
399 fprintf (f
, " comdat");
400 if (DECL_COMDAT_GROUP (node
->symbol
.decl
))
401 fprintf (f
, " comdat_group:%s",
402 IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node
->symbol
.decl
)));
403 if (DECL_ONE_ONLY (node
->symbol
.decl
))
404 fprintf (f
, " one_only");
405 if (DECL_SECTION_NAME (node
->symbol
.decl
))
406 fprintf (f
, " section_name:%s",
407 TREE_STRING_POINTER (DECL_SECTION_NAME (node
->symbol
.decl
)));
408 if (DECL_VISIBILITY_SPECIFIED (node
->symbol
.decl
))
409 fprintf (f
, " visibility_specified");
410 if (DECL_VISIBILITY (node
->symbol
.decl
))
411 fprintf (f
, " visibility:%s",
412 visibility_types
[DECL_VISIBILITY (node
->symbol
.decl
)]);
413 if (DECL_VIRTUAL_P (node
->symbol
.decl
))
414 fprintf (f
, " virtual");
415 if (DECL_ARTIFICIAL (node
->symbol
.decl
))
416 fprintf (f
, " artificial");
419 if (node
->symbol
.same_comdat_group
)
420 fprintf (f
, " Same comdat group as: %s/%i\n",
421 symtab_node_asm_name (node
->symbol
.same_comdat_group
),
422 node
->symbol
.same_comdat_group
->symbol
.order
);
423 if (node
->symbol
.next_sharing_asm_name
)
424 fprintf (f
, " next sharing asm name: %i\n",
425 node
->symbol
.next_sharing_asm_name
->symbol
.order
);
426 if (node
->symbol
.previous_sharing_asm_name
)
427 fprintf (f
, " previous sharing asm name: %i\n",
428 node
->symbol
.previous_sharing_asm_name
->symbol
.order
);
430 if (node
->symbol
.address_taken
)
431 fprintf (f
, " Address is taken.\n");
432 if (node
->symbol
.aux
)
434 fprintf (f
, " Aux:");
435 dump_addr (f
, " @", (void *)node
->symbol
.aux
);
438 fprintf (f
, " References: ");
439 ipa_dump_references (f
, &node
->symbol
.ref_list
);
440 fprintf (f
, " Referring: ");
441 ipa_dump_referring (f
, &node
->symbol
.ref_list
);
444 /* Dump symtab node. */
447 dump_symtab_node (FILE *f
, symtab_node node
)
449 if (symtab_function_p (node
))
450 dump_cgraph_node (f
, cgraph (node
));
451 else if (symtab_variable_p (node
))
452 dump_varpool_node (f
, varpool (node
));
455 /* Dump symbol table. */
458 dump_symtab (FILE *f
)
461 fprintf (f
, "Symbol table:\n\n");
462 FOR_EACH_SYMBOL (node
)
463 dump_symtab_node (f
, node
);
466 /* Dump symtab node NODE to stderr. */
469 debug_symtab_node (symtab_node node
)
471 dump_symtab_node (stderr
, node
);
474 /* Dump symbol table to stderr. */
479 dump_symtab (stderr
);
482 /* Verify common part of symtab nodes. */
485 verify_symtab_base (symtab_node node
)
487 bool error_found
= false;
488 symtab_node hashed_node
;
490 if (symtab_function_p (node
))
492 if (TREE_CODE (node
->symbol
.decl
) != FUNCTION_DECL
)
494 error ("function symbol is not function");
498 else if (symtab_variable_p (node
))
500 if (TREE_CODE (node
->symbol
.decl
) != VAR_DECL
)
502 error ("variable symbol is not variable");
508 error ("node has unknown type");
512 hashed_node
= symtab_get_node (node
->symbol
.decl
);
515 error ("node not found in symtab decl hashtable");
518 if (assembler_name_hash
)
520 hashed_node
= symtab_node_for_asm (DECL_ASSEMBLER_NAME (node
->symbol
.decl
));
521 if (hashed_node
&& hashed_node
->symbol
.previous_sharing_asm_name
)
523 error ("assembler name hash list corrupted");
528 if (hashed_node
== node
)
530 hashed_node
= hashed_node
->symbol
.next_sharing_asm_name
;
534 error ("node not found in symtab assembler name hash");
538 if (node
->symbol
.previous_sharing_asm_name
539 && node
->symbol
.previous_sharing_asm_name
->symbol
.next_sharing_asm_name
!= node
)
541 error ("double linked list of assembler names corrupted");
543 if (node
->symbol
.same_comdat_group
)
545 symtab_node n
= node
->symbol
.same_comdat_group
;
547 if (!DECL_ONE_ONLY (n
->symbol
.decl
))
549 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
552 if (n
->symbol
.type
!= node
->symbol
.type
)
554 error ("mixing different types of symbol in same comdat groups is not supported");
559 error ("node is alone in a comdat group");
564 if (!n
->symbol
.same_comdat_group
)
566 error ("same_comdat_group is not a circular list");
570 n
= n
->symbol
.same_comdat_group
;
577 /* Verify consistency of NODE. */
580 verify_symtab_node (symtab_node node
)
585 timevar_push (TV_CGRAPH_VERIFY
);
586 if (symtab_function_p (node
))
587 verify_cgraph_node (cgraph (node
));
589 if (verify_symtab_base (node
))
591 dump_symtab_node (stderr
, node
);
592 internal_error ("verify_symtab_node failed");
594 timevar_pop (TV_CGRAPH_VERIFY
);
597 /* Verify symbol table for internal consistency. */
603 FOR_EACH_SYMBOL (node
)
604 verify_symtab_node (node
);
607 #include "gt-symtab.h"