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"
33 /* Hash table used to convert declarations into nodes. */
34 static GTY((param_is (union symtab_node_def
))) htab_t symtab_hash
;
35 /* Hash table used to convert assembler names into nodes. */
36 static GTY((param_is (union symtab_node_def
))) htab_t assembler_name_hash
;
38 /* Linked list of symbol table nodes. */
39 symtab_node symtab_nodes
;
41 /* The order index of the next symtab node to be created. This is
42 used so that we can sort the cgraph nodes in order by when we saw
43 them, to support -fno-toplevel-reorder. */
46 /* Returns a hash code for P. */
49 hash_node (const void *p
)
51 const_symtab_node n
= (const_symtab_node
) p
;
52 return (hashval_t
) DECL_UID (n
->symbol
.decl
);
56 /* Returns nonzero if P1 and P2 are equal. */
59 eq_node (const void *p1
, const void *p2
)
61 const_symtab_node n1
= (const_symtab_node
) p1
;
62 const_symtab_node n2
= (const_symtab_node
) p2
;
63 return DECL_UID (n1
->symbol
.decl
) == DECL_UID (n2
->symbol
.decl
);
66 /* Returns a hash code for P. */
69 hash_node_by_assembler_name (const void *p
)
71 const_symtab_node n
= (const_symtab_node
) p
;
72 return (hashval_t
) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n
->symbol
.decl
));
75 /* Returns nonzero if P1 and P2 are equal. */
78 eq_assembler_name (const void *p1
, const void *p2
)
80 const_symtab_node n1
= (const_symtab_node
) p1
;
81 const_tree name
= (const_tree
)p2
;
82 return (decl_assembler_name_equal (n1
->symbol
.decl
, name
));
85 /* Insert NODE to assembler name hash. */
88 insert_to_assembler_name_hash (symtab_node node
)
90 gcc_checking_assert (!node
->symbol
.previous_sharing_asm_name
91 && !node
->symbol
.next_sharing_asm_name
);
92 if (assembler_name_hash
)
95 tree name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
97 aslot
= htab_find_slot_with_hash (assembler_name_hash
, name
,
98 decl_assembler_name_hash (name
),
100 gcc_assert (*aslot
!= node
);
101 node
->symbol
.next_sharing_asm_name
= (symtab_node
)*aslot
;
103 ((symtab_node
)*aslot
)->symbol
.previous_sharing_asm_name
= node
;
109 /* Remove NODE from assembler name hash. */
112 unlink_from_assembler_name_hash (symtab_node node
)
114 if (assembler_name_hash
)
116 if (node
->symbol
.next_sharing_asm_name
)
117 node
->symbol
.next_sharing_asm_name
->symbol
.previous_sharing_asm_name
118 = node
->symbol
.previous_sharing_asm_name
;
119 if (node
->symbol
.previous_sharing_asm_name
)
121 node
->symbol
.previous_sharing_asm_name
->symbol
.next_sharing_asm_name
122 = node
->symbol
.next_sharing_asm_name
;
126 tree name
= DECL_ASSEMBLER_NAME (node
->symbol
.decl
);
128 slot
= htab_find_slot_with_hash (assembler_name_hash
, name
,
129 decl_assembler_name_hash (name
),
131 gcc_assert (*slot
== node
);
132 if (!node
->symbol
.next_sharing_asm_name
)
133 htab_clear_slot (assembler_name_hash
, slot
);
135 *slot
= node
->symbol
.next_sharing_asm_name
;
141 /* Add node into symbol table. This function is not used directly, but via
142 cgraph/varpool node creation routines. */
145 symtab_register_node (symtab_node node
)
147 struct symtab_node_base key
;
150 node
->symbol
.next
= symtab_nodes
;
151 node
->symbol
.previous
= NULL
;
153 symtab_nodes
->symbol
.previous
= node
;
157 symtab_hash
= htab_create_ggc (10, hash_node
, eq_node
, NULL
);
158 key
.decl
= node
->symbol
.decl
;
159 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
, INSERT
);
163 insert_to_assembler_name_hash (node
);
165 node
->symbol
.order
= symtab_order
++;
167 ipa_empty_ref_list (&node
->symbol
.ref_list
);
170 /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree
174 symtab_insert_node_to_hashtable (symtab_node node
)
176 struct symtab_node_base key
;
180 symtab_hash
= htab_create_ggc (10, hash_node
, eq_node
, NULL
);
181 key
.decl
= node
->symbol
.decl
;
182 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
, INSERT
);
186 /* Remove node from symbol table. This function is not used directly, but via
187 cgraph/varpool node removal routines. */
190 symtab_unregister_node (symtab_node node
)
193 ipa_remove_all_references (&node
->symbol
.ref_list
);
194 ipa_remove_all_refering (&node
->symbol
.ref_list
);
196 if (node
->symbol
.same_comdat_group
)
199 for (prev
= node
->symbol
.same_comdat_group
;
200 prev
->symbol
.same_comdat_group
!= node
;
201 prev
= prev
->symbol
.same_comdat_group
)
203 if (node
->symbol
.same_comdat_group
== prev
)
204 prev
->symbol
.same_comdat_group
= NULL
;
206 prev
->symbol
.same_comdat_group
= node
->symbol
.same_comdat_group
;
207 node
->symbol
.same_comdat_group
= NULL
;
210 if (node
->symbol
.previous
)
211 node
->symbol
.previous
->symbol
.next
= node
->symbol
.next
;
213 symtab_nodes
= node
->symbol
.next
;
214 if (node
->symbol
.next
)
215 node
->symbol
.next
->symbol
.previous
= node
->symbol
.previous
;
216 node
->symbol
.next
= NULL
;
217 node
->symbol
.previous
= NULL
;
219 slot
= htab_find_slot (symtab_hash
, node
, NO_INSERT
);
222 symtab_node replacement_node
= NULL
;
223 if (symtab_function_p (node
))
224 replacement_node
= (symtab_node
)cgraph_find_replacement_node (cgraph (node
));
225 if (!replacement_node
)
226 htab_clear_slot (symtab_hash
, slot
);
228 *slot
= replacement_node
;
230 unlink_from_assembler_name_hash (node
);
233 /* Return symbol table node associated with DECL, if any,
234 and NULL otherwise. */
237 symtab_get_node (const_tree decl
)
240 struct symtab_node_base key
;
242 gcc_checking_assert (TREE_CODE (decl
) == FUNCTION_DECL
243 || (TREE_CODE (decl
) == VAR_DECL
244 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)
250 key
.decl
= CONST_CAST2 (tree
, const_tree
, decl
);
252 slot
= (symtab_node
*) htab_find_slot (symtab_hash
, &key
,
260 /* Remove symtab NODE from the symbol table. */
263 symtab_remove_node (symtab_node node
)
265 if (symtab_function_p (node
))
266 cgraph_remove_node (cgraph (node
));
267 else if (symtab_variable_p (node
))
268 varpool_remove_node (varpool (node
));
271 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
272 Return NULL if there's no such node. */
275 symtab_node_for_asm (const_tree asmname
)
280 if (!assembler_name_hash
)
282 assembler_name_hash
=
283 htab_create_ggc (10, hash_node_by_assembler_name
, eq_assembler_name
,
285 FOR_EACH_SYMBOL (node
)
286 insert_to_assembler_name_hash (node
);
289 slot
= htab_find_slot_with_hash (assembler_name_hash
, asmname
,
290 decl_assembler_name_hash (asmname
),
295 node
= (symtab_node
) *slot
;
301 /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
304 change_decl_assembler_name (tree decl
, tree name
)
306 symtab_node node
= NULL
;
308 /* We can have user ASM names on things, like global register variables, that
309 are not in the symbol table. */
310 if ((TREE_CODE (decl
) == VAR_DECL
311 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
312 || TREE_CODE (decl
) == FUNCTION_DECL
)
313 node
= symtab_get_node (decl
);
314 if (!DECL_ASSEMBLER_NAME_SET_P (decl
))
316 SET_DECL_ASSEMBLER_NAME (decl
, name
);
318 insert_to_assembler_name_hash (node
);
322 if (name
== DECL_ASSEMBLER_NAME (decl
))
326 unlink_from_assembler_name_hash (node
);
327 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
))
328 && DECL_RTL_SET_P (decl
))
329 warning (0, "%D renamed after being referenced in assembly", decl
);
331 SET_DECL_ASSEMBLER_NAME (decl
, name
);
333 insert_to_assembler_name_hash (node
);
337 /* Return printable assembler name of NODE.
338 This function is used only for debugging. When assembler name
339 is unknown go with identifier name. */
342 symtab_node_asm_name (symtab_node node
)
344 if (!DECL_ASSEMBLER_NAME_SET_P (node
->symbol
.decl
))
345 return lang_hooks
.decl_printable_name (node
->symbol
.decl
, 2);
346 return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node
->symbol
.decl
));
349 /* Return printable identifier name. */
352 symtab_node_name (symtab_node node
)
354 return lang_hooks
.decl_printable_name (node
->symbol
.decl
, 2);
357 static const char * const symtab_type_names
[] = {"symbol", "function", "variable"};
359 /* Dump base fields of symtab nodes. Not to be used directly. */
362 dump_symtab_base (FILE *f
, symtab_node node
)
364 static const char * const visibility_types
[] = {
365 "default", "protected", "hidden", "internal"
368 fprintf (f
, "%s/%i (%s)",
369 symtab_node_asm_name (node
),
371 symtab_node_name (node
));
372 dump_addr (f
, " @", (void *)node
);
373 fprintf (f
, "\n Type: %s\n", symtab_type_names
[node
->symbol
.type
]);
374 fprintf (f
, " Visibility:");
376 if (node
->symbol
.in_other_partition
)
377 fprintf (f
, " in_other_partition");
378 if (node
->symbol
.used_from_other_partition
)
379 fprintf (f
, " used_from_other_partition");
380 if (node
->symbol
.resolution
!= LDPR_UNKNOWN
)
382 ld_plugin_symbol_resolution_names
[(int)node
->symbol
.resolution
]);
383 if (TREE_ASM_WRITTEN (node
->symbol
.decl
))
384 fprintf (f
, " asm_written");
385 if (DECL_EXTERNAL (node
->symbol
.decl
))
386 fprintf (f
, " external");
387 if (TREE_PUBLIC (node
->symbol
.decl
))
388 fprintf (f
, " public");
389 if (DECL_COMMON (node
->symbol
.decl
))
390 fprintf (f
, " common");
391 if (DECL_WEAK (node
->symbol
.decl
))
392 fprintf (f
, " weak");
393 if (DECL_DLLIMPORT_P (node
->symbol
.decl
))
394 fprintf (f
, " dll_import");
395 if (DECL_COMDAT (node
->symbol
.decl
))
396 fprintf (f
, " comdat");
397 if (DECL_COMDAT_GROUP (node
->symbol
.decl
))
398 fprintf (f
, " comdat_group:%s",
399 IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node
->symbol
.decl
)));
400 if (DECL_ONE_ONLY (node
->symbol
.decl
))
401 fprintf (f
, " one_only");
402 if (DECL_SECTION_NAME (node
->symbol
.decl
))
403 fprintf (f
, " section_name:%s",
404 IDENTIFIER_POINTER (DECL_SECTION_NAME (node
->symbol
.decl
)));
405 if (DECL_VISIBILITY_SPECIFIED (node
->symbol
.decl
))
406 fprintf (f
, " visibility_specified");
407 if (DECL_VISIBILITY (node
->symbol
.decl
))
408 fprintf (f
, " visibility:%s",
409 visibility_types
[DECL_VISIBILITY (node
->symbol
.decl
)]);
410 if (DECL_VIRTUAL_P (node
->symbol
.decl
))
411 fprintf (f
, " virtual");
412 if (DECL_ARTIFICIAL (node
->symbol
.decl
))
413 fprintf (f
, " artificial");
416 if (node
->symbol
.same_comdat_group
)
417 fprintf (f
, " Same comdat group as: %s/%i\n",
418 symtab_node_asm_name (node
->symbol
.same_comdat_group
),
419 node
->symbol
.same_comdat_group
->symbol
.order
);
420 if (node
->symbol
.next_sharing_asm_name
)
421 fprintf (f
, " next sharing asm name: %i\n",
422 node
->symbol
.same_comdat_group
->symbol
.order
);
423 if (node
->symbol
.previous_sharing_asm_name
)
424 fprintf (f
, " previous sharing asm name: %i\n",
425 node
->symbol
.same_comdat_group
->symbol
.order
);
427 if (node
->symbol
.address_taken
)
428 fprintf (f
, " Address is taken.");
430 fprintf (f
, " References: ");
431 ipa_dump_references (f
, &node
->symbol
.ref_list
);
432 fprintf (f
, " Refering: ");
433 ipa_dump_refering (f
, &node
->symbol
.ref_list
);
436 /* Dump symtab node. */
439 dump_symtab_node (FILE *f
, symtab_node node
)
441 if (symtab_function_p (node
))
442 dump_cgraph_node (f
, cgraph (node
));
443 else if (symtab_variable_p (node
))
444 dump_varpool_node (f
, varpool (node
));
447 /* Dump symbol table. */
450 dump_symtab (FILE *f
)
453 fprintf (f
, "Symbol table:\n\n");
454 FOR_EACH_SYMBOL (node
)
455 dump_symtab_node (f
, node
);
458 /* Dump symtab node NODE to stderr. */
461 debug_symtab_node (symtab_node node
)
463 dump_symtab_node (stderr
, node
);
466 /* Dump symbol table to stderr. */
471 dump_symtab (stderr
);
474 #include "gt-symtab.h"