]>
Commit | Line | Data |
---|---|---|
2aae7680 JH |
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" | |
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. */ | |
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; | |
2aae7680 JH |
38 | |
39 | /* Linked list of symbol table nodes. */ | |
40 | symtab_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. */ | |
45 | int symtab_order; | |
46 | ||
1ab24192 JH |
47 | /* Returns a hash code for P. */ |
48 | ||
49 | static hashval_t | |
50 | hash_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 | ||
59 | static int | |
60 | eq_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 | ||
69 | static hashval_t | |
70 | hash_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 | ||
78 | static int | |
79 | eq_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 | ||
88 | static void | |
89 | insert_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 | ||
112 | static void | |
113 | unlink_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 | ||
145 | void | |
146 | symtab_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 | ||
174 | void | |
175 | symtab_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 | ||
190 | void | |
191 | symtab_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 | ||
237 | symtab_node | |
238 | symtab_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 | ||
263 | void | |
264 | symtab_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 | ||
275 | symtab_node | |
276 | symtab_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 | ||
304 | void | |
305 | change_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 | ||
342 | const char * | |
343 | symtab_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 | ||
352 | const char * | |
353 | symtab_node_name (symtab_node node) | |
354 | { | |
355 | return lang_hooks.decl_printable_name (node->symbol.decl, 2); | |
356 | } | |
357 | ||
358 | static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; | |
359 | ||
360 | /* Dump base fields of symtab nodes. Not to be used directly. */ | |
361 | ||
362 | void | |
363 | dump_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 | ||
446 | void | |
447 | dump_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 | ||
457 | void | |
458 | dump_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 | ||
468 | DEBUG_FUNCTION void | |
469 | debug_symtab_node (symtab_node node) | |
470 | { | |
471 | dump_symtab_node (stderr, node); | |
472 | } | |
473 | ||
474 | /* Dump symbol table to stderr. */ | |
475 | ||
476 | DEBUG_FUNCTION void | |
477 | debug_symtab (void) | |
478 | { | |
479 | dump_symtab (stderr); | |
480 | } | |
481 | ||
474ffc72 JH |
482 | /* Verify common part of symtab nodes. */ |
483 | ||
484 | DEBUG_FUNCTION bool | |
485 | verify_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 | ||
579 | DEBUG_FUNCTION void | |
580 | verify_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 | ||
599 | DEBUG_FUNCTION void | |
600 | verify_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" |