]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/symtab.c
re PR tree-optimization/52979 (likely wrong code bug w/packed bitfields)
[thirdparty/gcc.git] / gcc / symtab.c
CommitLineData
2aae7680
JH
1/* Symbol table.
2 Copyright (C) 2012 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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"
1ab24192
JH
33
34/* Hash table used to convert declarations into nodes. */
35static GTY((param_is (union symtab_node_def))) htab_t symtab_hash;
36/* Hash table used to convert assembler names into nodes. */
37static GTY((param_is (union symtab_node_def))) htab_t assembler_name_hash;
2aae7680
JH
38
39/* Linked list of symbol table nodes. */
40symtab_node symtab_nodes;
41
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. */
45int symtab_order;
46
1ab24192
JH
47/* Returns a hash code for P. */
48
49static hashval_t
50hash_node (const void *p)
51{
52 const_symtab_node n = (const_symtab_node ) p;
53 return (hashval_t) DECL_UID (n->symbol.decl);
54}
55
56
57/* Returns nonzero if P1 and P2 are equal. */
58
59static int
60eq_node (const void *p1, const void *p2)
61{
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);
65}
66
67/* Returns a hash code for P. */
68
69static hashval_t
70hash_node_by_assembler_name (const void *p)
71{
72 const_symtab_node n = (const_symtab_node) p;
73 return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->symbol.decl));
74}
75
76/* Returns nonzero if P1 and P2 are equal. */
77
78static int
79eq_assembler_name (const void *p1, const void *p2)
80{
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));
84}
85
86/* Insert NODE to assembler name hash. */
87
88static void
89insert_to_assembler_name_hash (symtab_node node)
90{
91 gcc_checking_assert (!node->symbol.previous_sharing_asm_name
92 && !node->symbol.next_sharing_asm_name);
93 if (assembler_name_hash)
94 {
95 void **aslot;
96 tree name = DECL_ASSEMBLER_NAME (node->symbol.decl);
97
98 aslot = htab_find_slot_with_hash (assembler_name_hash, name,
99 decl_assembler_name_hash (name),
100 INSERT);
101 gcc_assert (*aslot != node);
102 node->symbol.next_sharing_asm_name = (symtab_node)*aslot;
103 if (*aslot != NULL)
104 ((symtab_node)*aslot)->symbol.previous_sharing_asm_name = node;
105 *aslot = node;
106 }
107
108}
109
110/* Remove NODE from assembler name hash. */
111
112static void
113unlink_from_assembler_name_hash (symtab_node node)
114{
115 if (assembler_name_hash)
116 {
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)
121 {
122 node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name
123 = node->symbol.next_sharing_asm_name;
124 }
125 else
126 {
127 tree name = DECL_ASSEMBLER_NAME (node->symbol.decl);
128 void **slot;
129 slot = htab_find_slot_with_hash (assembler_name_hash, name,
130 decl_assembler_name_hash (name),
131 NO_INSERT);
132 gcc_assert (*slot == node);
133 if (!node->symbol.next_sharing_asm_name)
134 htab_clear_slot (assembler_name_hash, slot);
135 else
136 *slot = node->symbol.next_sharing_asm_name;
137 }
138 }
139}
140
141
2aae7680
JH
142/* Add node into symbol table. This function is not used directly, but via
143 cgraph/varpool node creation routines. */
144
145void
146symtab_register_node (symtab_node node)
147{
1ab24192
JH
148 struct symtab_node_base key;
149 symtab_node *slot;
150
2aae7680
JH
151 node->symbol.next = symtab_nodes;
152 node->symbol.previous = NULL;
153 if (symtab_nodes)
154 symtab_nodes->symbol.previous = node;
155 symtab_nodes = node;
156
1ab24192
JH
157 if (!symtab_hash)
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);
161 if (*slot == NULL)
162 *slot = node;
163
164 insert_to_assembler_name_hash (node);
165
2aae7680
JH
166 node->symbol.order = symtab_order++;
167
168 ipa_empty_ref_list (&node->symbol.ref_list);
169}
170
1ab24192
JH
171/* Make NODE to be the one symtab hash is pointing to. Used when reshaping tree
172 of inline clones. */
173
174void
175symtab_insert_node_to_hashtable (symtab_node node)
176{
177 struct symtab_node_base key;
178 symtab_node *slot;
179
180 if (!symtab_hash)
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);
184 *slot = node;
185}
186
2aae7680
JH
187/* Remove node from symbol table. This function is not used directly, but via
188 cgraph/varpool node removal routines. */
189
190void
191symtab_unregister_node (symtab_node node)
192{
1ab24192 193 void **slot;
2aae7680 194 ipa_remove_all_references (&node->symbol.ref_list);
5932a4d4 195 ipa_remove_all_referring (&node->symbol.ref_list);
2aae7680
JH
196
197 if (node->symbol.same_comdat_group)
198 {
199 symtab_node prev;
200 for (prev = node->symbol.same_comdat_group;
201 prev->symbol.same_comdat_group != node;
202 prev = prev->symbol.same_comdat_group)
203 ;
204 if (node->symbol.same_comdat_group == prev)
205 prev->symbol.same_comdat_group = NULL;
206 else
207 prev->symbol.same_comdat_group = node->symbol.same_comdat_group;
208 node->symbol.same_comdat_group = NULL;
209 }
210
211 if (node->symbol.previous)
212 node->symbol.previous->symbol.next = node->symbol.next;
213 else
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;
1ab24192
JH
219
220 slot = htab_find_slot (symtab_hash, node, NO_INSERT);
221 if (*slot == node)
222 {
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);
228 else
229 *slot = replacement_node;
230 }
231 unlink_from_assembler_name_hash (node);
232}
233
234/* Return symbol table node associated with DECL, if any,
235 and NULL otherwise. */
236
237symtab_node
238symtab_get_node (const_tree decl)
239{
240 symtab_node *slot;
241 struct symtab_node_base key;
242
243 gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
244 || (TREE_CODE (decl) == VAR_DECL
245 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
246 || in_lto_p)));
247
248 if (!symtab_hash)
249 return NULL;
250
251 key.decl = CONST_CAST2 (tree, const_tree, decl);
252
253 slot = (symtab_node *) htab_find_slot (symtab_hash, &key,
254 NO_INSERT);
255
256 if (slot)
257 return *slot;
258 return NULL;
2aae7680
JH
259}
260
261/* Remove symtab NODE from the symbol table. */
262
263void
264symtab_remove_node (symtab_node node)
265{
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));
270}
1ab24192
JH
271
272/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
273 Return NULL if there's no such node. */
274
275symtab_node
276symtab_node_for_asm (const_tree asmname)
277{
278 symtab_node node;
279 void **slot;
280
281 if (!assembler_name_hash)
282 {
283 assembler_name_hash =
284 htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
285 NULL);
286 FOR_EACH_SYMBOL (node)
287 insert_to_assembler_name_hash (node);
288 }
289
290 slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
291 decl_assembler_name_hash (asmname),
292 NO_INSERT);
293
294 if (slot)
295 {
296 node = (symtab_node) *slot;
297 return node;
298 }
299 return NULL;
300}
301
302/* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
303
304void
305change_decl_assembler_name (tree decl, tree name)
306{
307 symtab_node node = NULL;
308
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))
316 {
317 SET_DECL_ASSEMBLER_NAME (decl, name);
318 if (node)
319 insert_to_assembler_name_hash (node);
320 }
321 else
322 {
323 if (name == DECL_ASSEMBLER_NAME (decl))
324 return;
325
326 if (node)
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);
331
332 SET_DECL_ASSEMBLER_NAME (decl, name);
333 if (node)
334 insert_to_assembler_name_hash (node);
335 }
336}
337
8f940ee6
JH
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. */
341
342const char *
343symtab_node_asm_name (symtab_node node)
344{
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));
348}
349
350/* Return printable identifier name. */
351
352const char *
353symtab_node_name (symtab_node node)
354{
355 return lang_hooks.decl_printable_name (node->symbol.decl, 2);
356}
357
358static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
359
360/* Dump base fields of symtab nodes. Not to be used directly. */
361
362void
363dump_symtab_base (FILE *f, symtab_node node)
364{
365 static const char * const visibility_types[] = {
366 "default", "protected", "hidden", "internal"
367 };
368
369 fprintf (f, "%s/%i (%s)",
370 symtab_node_asm_name (node),
371 node->symbol.order,
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:");
376
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");
ead84f73
JH
381 if (node->symbol.force_output)
382 fprintf (f, " force_output");
8f940ee6
JH
383 if (node->symbol.resolution != LDPR_UNKNOWN)
384 fprintf (f, " %s",
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",
f68c0487 407 TREE_STRING_POINTER (DECL_SECTION_NAME (node->symbol.decl)));
8f940ee6
JH
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");
417 fprintf (f, "\n");
418
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",
fe0bd630 425 node->symbol.next_sharing_asm_name->symbol.order);
8f940ee6
JH
426 if (node->symbol.previous_sharing_asm_name)
427 fprintf (f, " previous sharing asm name: %i\n",
fe0bd630 428 node->symbol.previous_sharing_asm_name->symbol.order);
8f940ee6
JH
429
430 if (node->symbol.address_taken)
fe0bd630 431 fprintf (f, " Address is taken.\n");
66058468
JH
432 if (node->symbol.aux)
433 {
434 fprintf (f, " Aux:");
435 dump_addr (f, " @", (void *)node->symbol.aux);
436 }
8f940ee6
JH
437
438 fprintf (f, " References: ");
439 ipa_dump_references (f, &node->symbol.ref_list);
5932a4d4
JH
440 fprintf (f, " Referring: ");
441 ipa_dump_referring (f, &node->symbol.ref_list);
8f940ee6
JH
442}
443
444/* Dump symtab node. */
445
446void
447dump_symtab_node (FILE *f, symtab_node node)
448{
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));
453}
454
455/* Dump symbol table. */
456
457void
458dump_symtab (FILE *f)
459{
460 symtab_node node;
461 fprintf (f, "Symbol table:\n\n");
462 FOR_EACH_SYMBOL (node)
463 dump_symtab_node (f, node);
464}
465
466/* Dump symtab node NODE to stderr. */
467
468DEBUG_FUNCTION void
469debug_symtab_node (symtab_node node)
470{
471 dump_symtab_node (stderr, node);
472}
473
474/* Dump symbol table to stderr. */
475
476DEBUG_FUNCTION void
477debug_symtab (void)
478{
479 dump_symtab (stderr);
480}
481
474ffc72
JH
482/* Verify common part of symtab nodes. */
483
484DEBUG_FUNCTION bool
485verify_symtab_base (symtab_node node)
486{
487 bool error_found = false;
488 symtab_node hashed_node;
489
490 if (symtab_function_p (node))
491 {
492 if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL)
493 {
494 error ("function symbol is not function");
495 error_found = true;
496 }
497 }
498 else if (symtab_variable_p (node))
499 {
500 if (TREE_CODE (node->symbol.decl) != VAR_DECL)
501 {
502 error ("variable symbol is not variable");
503 error_found = true;
504 }
505 }
506 else
507 {
508 error ("node has unknown type");
509 error_found = true;
510 }
511
512 hashed_node = symtab_get_node (node->symbol.decl);
513 if (!hashed_node)
514 {
515 error ("node not found in symtab decl hashtable");
516 error_found = true;
517 }
518 if (assembler_name_hash)
519 {
520 hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->symbol.decl));
521 if (hashed_node && hashed_node->symbol.previous_sharing_asm_name)
522 {
523 error ("assembler name hash list corrupted");
524 error_found = true;
525 }
526 while (hashed_node)
527 {
528 if (hashed_node == node)
529 break;
530 hashed_node = hashed_node->symbol.next_sharing_asm_name;
531 }
532 if (!hashed_node)
533 {
534 error ("node not found in symtab assembler name hash");
535 error_found = true;
536 }
537 }
538 if (node->symbol.previous_sharing_asm_name
539 && node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node)
540 {
541 error ("double linked list of assembler names corrupted");
542 }
543 if (node->symbol.same_comdat_group)
544 {
545 symtab_node n = node->symbol.same_comdat_group;
546
547 if (!DECL_ONE_ONLY (n->symbol.decl))
548 {
549 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
550 error_found = true;
551 }
552 if (n->symbol.type != node->symbol.type)
553 {
554 error ("mixing different types of symbol in same comdat groups is not supported");
555 error_found = true;
556 }
557 if (n == node)
558 {
559 error ("node is alone in a comdat group");
560 error_found = true;
561 }
562 do
563 {
564 if (!n->symbol.same_comdat_group)
565 {
566 error ("same_comdat_group is not a circular list");
567 error_found = true;
568 break;
569 }
570 n = n->symbol.same_comdat_group;
571 }
572 while (n != node);
573 }
574 return error_found;
575}
576
577/* Verify consistency of NODE. */
578
579DEBUG_FUNCTION void
580verify_symtab_node (symtab_node node)
581{
582 if (seen_error ())
583 return;
584
585 timevar_push (TV_CGRAPH_VERIFY);
586 if (symtab_function_p (node))
587 verify_cgraph_node (cgraph (node));
588 else
589 if (verify_symtab_base (node))
590 {
591 dump_symtab_node (stderr, node);
592 internal_error ("verify_symtab_node failed");
593 }
594 timevar_pop (TV_CGRAPH_VERIFY);
595}
596
597/* Verify symbol table for internal consistency. */
598
599DEBUG_FUNCTION void
600verify_symtab (void)
601{
602 symtab_node node;
603 FOR_EACH_SYMBOL (node)
604 verify_symtab_node (node);
605}
606
1ab24192 607#include "gt-symtab.h"