]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/symtab.c
cgraph.c (cgraph_node_name): Remove.
[thirdparty/gcc.git] / gcc / symtab.c
1 /* Symbol table.
2 Copyright (C) 2012 Free Software Foundation, Inc.
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"
27 #include "langhooks.h"
28 #include "hashtab.h"
29 #include "ggc.h"
30 #include "cgraph.h"
31 #include "diagnostic.h"
32
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;
37
38 /* Linked list of symbol table nodes. */
39 symtab_node symtab_nodes;
40
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. */
44 int symtab_order;
45
46 /* Returns a hash code for P. */
47
48 static hashval_t
49 hash_node (const void *p)
50 {
51 const_symtab_node n = (const_symtab_node ) p;
52 return (hashval_t) DECL_UID (n->symbol.decl);
53 }
54
55
56 /* Returns nonzero if P1 and P2 are equal. */
57
58 static int
59 eq_node (const void *p1, const void *p2)
60 {
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);
64 }
65
66 /* Returns a hash code for P. */
67
68 static hashval_t
69 hash_node_by_assembler_name (const void *p)
70 {
71 const_symtab_node n = (const_symtab_node) p;
72 return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->symbol.decl));
73 }
74
75 /* Returns nonzero if P1 and P2 are equal. */
76
77 static int
78 eq_assembler_name (const void *p1, const void *p2)
79 {
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));
83 }
84
85 /* Insert NODE to assembler name hash. */
86
87 static void
88 insert_to_assembler_name_hash (symtab_node node)
89 {
90 gcc_checking_assert (!node->symbol.previous_sharing_asm_name
91 && !node->symbol.next_sharing_asm_name);
92 if (assembler_name_hash)
93 {
94 void **aslot;
95 tree name = DECL_ASSEMBLER_NAME (node->symbol.decl);
96
97 aslot = htab_find_slot_with_hash (assembler_name_hash, name,
98 decl_assembler_name_hash (name),
99 INSERT);
100 gcc_assert (*aslot != node);
101 node->symbol.next_sharing_asm_name = (symtab_node)*aslot;
102 if (*aslot != NULL)
103 ((symtab_node)*aslot)->symbol.previous_sharing_asm_name = node;
104 *aslot = node;
105 }
106
107 }
108
109 /* Remove NODE from assembler name hash. */
110
111 static void
112 unlink_from_assembler_name_hash (symtab_node node)
113 {
114 if (assembler_name_hash)
115 {
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)
120 {
121 node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name
122 = node->symbol.next_sharing_asm_name;
123 }
124 else
125 {
126 tree name = DECL_ASSEMBLER_NAME (node->symbol.decl);
127 void **slot;
128 slot = htab_find_slot_with_hash (assembler_name_hash, name,
129 decl_assembler_name_hash (name),
130 NO_INSERT);
131 gcc_assert (*slot == node);
132 if (!node->symbol.next_sharing_asm_name)
133 htab_clear_slot (assembler_name_hash, slot);
134 else
135 *slot = node->symbol.next_sharing_asm_name;
136 }
137 }
138 }
139
140
141 /* Add node into symbol table. This function is not used directly, but via
142 cgraph/varpool node creation routines. */
143
144 void
145 symtab_register_node (symtab_node node)
146 {
147 struct symtab_node_base key;
148 symtab_node *slot;
149
150 node->symbol.next = symtab_nodes;
151 node->symbol.previous = NULL;
152 if (symtab_nodes)
153 symtab_nodes->symbol.previous = node;
154 symtab_nodes = node;
155
156 if (!symtab_hash)
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);
160 if (*slot == NULL)
161 *slot = node;
162
163 insert_to_assembler_name_hash (node);
164
165 node->symbol.order = symtab_order++;
166
167 ipa_empty_ref_list (&node->symbol.ref_list);
168 }
169
170 /* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree
171 of inline clones. */
172
173 void
174 symtab_insert_node_to_hashtable (symtab_node node)
175 {
176 struct symtab_node_base key;
177 symtab_node *slot;
178
179 if (!symtab_hash)
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);
183 *slot = node;
184 }
185
186 /* Remove node from symbol table. This function is not used directly, but via
187 cgraph/varpool node removal routines. */
188
189 void
190 symtab_unregister_node (symtab_node node)
191 {
192 void **slot;
193 ipa_remove_all_references (&node->symbol.ref_list);
194 ipa_remove_all_refering (&node->symbol.ref_list);
195
196 if (node->symbol.same_comdat_group)
197 {
198 symtab_node prev;
199 for (prev = node->symbol.same_comdat_group;
200 prev->symbol.same_comdat_group != node;
201 prev = prev->symbol.same_comdat_group)
202 ;
203 if (node->symbol.same_comdat_group == prev)
204 prev->symbol.same_comdat_group = NULL;
205 else
206 prev->symbol.same_comdat_group = node->symbol.same_comdat_group;
207 node->symbol.same_comdat_group = NULL;
208 }
209
210 if (node->symbol.previous)
211 node->symbol.previous->symbol.next = node->symbol.next;
212 else
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;
218
219 slot = htab_find_slot (symtab_hash, node, NO_INSERT);
220 if (*slot == node)
221 {
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);
227 else
228 *slot = replacement_node;
229 }
230 unlink_from_assembler_name_hash (node);
231 }
232
233 /* Return symbol table node associated with DECL, if any,
234 and NULL otherwise. */
235
236 symtab_node
237 symtab_get_node (const_tree decl)
238 {
239 symtab_node *slot;
240 struct symtab_node_base key;
241
242 gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
243 || (TREE_CODE (decl) == VAR_DECL
244 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
245 || in_lto_p)));
246
247 if (!symtab_hash)
248 return NULL;
249
250 key.decl = CONST_CAST2 (tree, const_tree, decl);
251
252 slot = (symtab_node *) htab_find_slot (symtab_hash, &key,
253 NO_INSERT);
254
255 if (slot)
256 return *slot;
257 return NULL;
258 }
259
260 /* Remove symtab NODE from the symbol table. */
261
262 void
263 symtab_remove_node (symtab_node node)
264 {
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));
269 }
270
271 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
272 Return NULL if there's no such node. */
273
274 symtab_node
275 symtab_node_for_asm (const_tree asmname)
276 {
277 symtab_node node;
278 void **slot;
279
280 if (!assembler_name_hash)
281 {
282 assembler_name_hash =
283 htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
284 NULL);
285 FOR_EACH_SYMBOL (node)
286 insert_to_assembler_name_hash (node);
287 }
288
289 slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
290 decl_assembler_name_hash (asmname),
291 NO_INSERT);
292
293 if (slot)
294 {
295 node = (symtab_node) *slot;
296 return node;
297 }
298 return NULL;
299 }
300
301 /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
302
303 void
304 change_decl_assembler_name (tree decl, tree name)
305 {
306 symtab_node node = NULL;
307
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))
315 {
316 SET_DECL_ASSEMBLER_NAME (decl, name);
317 if (node)
318 insert_to_assembler_name_hash (node);
319 }
320 else
321 {
322 if (name == DECL_ASSEMBLER_NAME (decl))
323 return;
324
325 if (node)
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);
330
331 SET_DECL_ASSEMBLER_NAME (decl, name);
332 if (node)
333 insert_to_assembler_name_hash (node);
334 }
335 }
336
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. */
340
341 const char *
342 symtab_node_asm_name (symtab_node node)
343 {
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));
347 }
348
349 /* Return printable identifier name. */
350
351 const char *
352 symtab_node_name (symtab_node node)
353 {
354 return lang_hooks.decl_printable_name (node->symbol.decl, 2);
355 }
356
357 static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
358
359 /* Dump base fields of symtab nodes. Not to be used directly. */
360
361 void
362 dump_symtab_base (FILE *f, symtab_node node)
363 {
364 static const char * const visibility_types[] = {
365 "default", "protected", "hidden", "internal"
366 };
367
368 fprintf (f, "%s/%i (%s)",
369 symtab_node_asm_name (node),
370 node->symbol.order,
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:");
375
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)
381 fprintf (f, " %s",
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");
414 fprintf (f, "\n");
415
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);
426
427 if (node->symbol.address_taken)
428 fprintf (f, " Address is taken.");
429
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);
434 }
435
436 /* Dump symtab node. */
437
438 void
439 dump_symtab_node (FILE *f, symtab_node node)
440 {
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));
445 }
446
447 /* Dump symbol table. */
448
449 void
450 dump_symtab (FILE *f)
451 {
452 symtab_node node;
453 fprintf (f, "Symbol table:\n\n");
454 FOR_EACH_SYMBOL (node)
455 dump_symtab_node (f, node);
456 }
457
458 /* Dump symtab node NODE to stderr. */
459
460 DEBUG_FUNCTION void
461 debug_symtab_node (symtab_node node)
462 {
463 dump_symtab_node (stderr, node);
464 }
465
466 /* Dump symbol table to stderr. */
467
468 DEBUG_FUNCTION void
469 debug_symtab (void)
470 {
471 dump_symtab (stderr);
472 }
473
474 #include "gt-symtab.h"