summaryrefslogtreecommitdiff
path: root/gcc/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r--gcc/symtab.c831
1 files changed, 411 insertions, 420 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 005057384e3..8f04758da0a 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -272,111 +272,6 @@ symtab_prevail_in_asm_name_hash (symtab_node *node)
insert_to_assembler_name_hash (node, false);
}
-
-/* Add node into symbol table. This function is not used directly, but via
- cgraph/varpool node creation routines. */
-
-void
-symtab_register_node (symtab_node *node)
-{
- node->next = symtab_nodes;
- node->previous = NULL;
- if (symtab_nodes)
- symtab_nodes->previous = node;
- symtab_nodes = node;
-
- if (!node->decl->decl_with_vis.symtab_node)
- node->decl->decl_with_vis.symtab_node = node;
-
- node->ref_list.clear ();
-
- node->order = symtab_order++;
-
- /* Be sure to do this last; C++ FE might create new nodes via
- DECL_ASSEMBLER_NAME langhook! */
- insert_to_assembler_name_hash (node, false);
-}
-
-/* Remove NODE from same comdat group. */
-
-void
-symtab_remove_from_same_comdat_group (symtab_node *node)
-{
- if (node->same_comdat_group)
- {
- symtab_node *prev;
- for (prev = node->same_comdat_group;
- prev->same_comdat_group != node;
- prev = prev->same_comdat_group)
- ;
- if (node->same_comdat_group == prev)
- prev->same_comdat_group = NULL;
- else
- prev->same_comdat_group = node->same_comdat_group;
- node->same_comdat_group = NULL;
- node->set_comdat_group (NULL_TREE);
- }
-}
-
-/* Remove node from symbol table. This function is not used directly, but via
- cgraph/varpool node removal routines. */
-
-void
-symtab_unregister_node (symtab_node *node)
-{
- node->remove_all_references ();
- node->remove_all_referring ();
-
- /* Remove reference to section. */
- node->set_section_for_node (NULL);
-
- symtab_remove_from_same_comdat_group (node);
-
- if (node->previous)
- node->previous->next = node->next;
- else
- symtab_nodes = node->next;
- if (node->next)
- node->next->previous = node->previous;
- node->next = NULL;
- node->previous = NULL;
-
- /* During LTO symtab merging we temporarily corrupt decl to symtab node
- hash. */
- gcc_assert (node->decl->decl_with_vis.symtab_node || in_lto_p);
- if (node->decl->decl_with_vis.symtab_node == node)
- {
- symtab_node *replacement_node = NULL;
- if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
- replacement_node = cgraph_find_replacement_node (cnode);
- node->decl->decl_with_vis.symtab_node = replacement_node;
- }
- if (!is_a <varpool_node *> (node) || !DECL_HARD_REGISTER (node->decl))
- unlink_from_assembler_name_hash (node, false);
- if (node->in_init_priority_hash)
- {
- struct symbol_priority_map in;
- void **slot;
- in.symbol = node;
-
- slot = htab_find_slot (init_priority_hash, &in, NO_INSERT);
- if (slot)
- htab_clear_slot (init_priority_hash, slot);
- }
-}
-
-
-/* Remove symtab NODE from the symbol table. */
-
-void
-symtab_remove_node (symtab_node *node)
-{
- if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
- cgraph_remove_node (cnode);
- else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
- varpool_remove_node (vnode);
-}
-
/* Initalize asm name hash unless. */
void
@@ -427,7 +322,7 @@ change_decl_assembler_name (tree decl, tree name)
if ((TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
|| TREE_CODE (decl) == FUNCTION_DECL)
- node = symtab_get_node (decl);
+ node = symtab_node::get (decl);
if (!DECL_ASSEMBLER_NAME_SET_P (decl))
{
SET_DECL_ASSEMBLER_NAME (decl, name);
@@ -459,20 +354,154 @@ change_decl_assembler_name (tree decl, tree name)
}
}
+/* Return true when RESOLUTION indicate that linker will use
+ the symbol from non-LTO object files. */
+
+bool
+resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
+{
+ return (resolution == LDPR_PREVAILING_DEF
+ || resolution == LDPR_PREEMPTED_REG
+ || resolution == LDPR_RESOLVED_EXEC
+ || resolution == LDPR_RESOLVED_DYN);
+}
+
+/* Hash sections by their names. */
+
+static hashval_t
+hash_section_hash_entry (const void *p)
+{
+ const section_hash_entry *n = (const section_hash_entry *) p;
+ return htab_hash_string (n->name);
+}
+
+/* Return true if section P1 name equals to P2. */
+
+static int
+eq_sections (const void *p1, const void *p2)
+{
+ const section_hash_entry *n1 = (const section_hash_entry *) p1;
+ const char *name = (const char *)p2;
+ return n1->name == name || !strcmp (n1->name, name);
+}
+
+/* Add node into symbol table. This function is not used directly, but via
+ cgraph/varpool node creation routines. */
+
+void
+symtab_node::register_symbol (void)
+{
+ next = symtab_nodes;
+ previous = NULL;
+ if (symtab_nodes)
+ symtab_nodes->previous = this;
+ symtab_nodes = this;
+
+ if (!decl->decl_with_vis.symtab_node)
+ decl->decl_with_vis.symtab_node = this;
+
+ ref_list.clear ();
+
+ order = symtab_order++;
+
+ /* Be sure to do this last; C++ FE might create new nodes via
+ DECL_ASSEMBLER_NAME langhook! */
+ insert_to_assembler_name_hash (this, false);
+}
+
+/* Remove NODE from same comdat group. */
+
+void
+symtab_node::remove_from_same_comdat_group (void)
+{
+ if (same_comdat_group)
+ {
+ symtab_node *prev;
+ for (prev = same_comdat_group;
+ prev->same_comdat_group != this;
+ prev = prev->same_comdat_group)
+ ;
+ if (same_comdat_group == prev)
+ prev->same_comdat_group = NULL;
+ else
+ prev->same_comdat_group = same_comdat_group;
+ same_comdat_group = NULL;
+ set_comdat_group (NULL);
+ }
+}
+
+/* Remove node from symbol table. This function is not used directly, but via
+ cgraph/varpool node removal routines. */
+
+void
+symtab_node::unregister (void)
+{
+ remove_all_references ();
+ remove_all_referring ();
+
+ /* Remove reference to section. */
+ set_section_for_node (NULL);
+
+ remove_from_same_comdat_group ();
+
+ if (previous)
+ previous->next = next;
+ else
+ symtab_nodes = next;
+ if (next)
+ next->previous = previous;
+ next = NULL;
+ previous = NULL;
+
+ /* During LTO symtab merging we temporarily corrupt decl to symtab node
+ hash. */
+ gcc_assert (decl->decl_with_vis.symtab_node || in_lto_p);
+ if (decl->decl_with_vis.symtab_node == this)
+ {
+ symtab_node *replacement_node = NULL;
+ if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
+ replacement_node = cnode->find_replacement ();
+ decl->decl_with_vis.symtab_node = replacement_node;
+ }
+ if (!is_a <varpool_node *> (this) || !DECL_HARD_REGISTER (decl))
+ unlink_from_assembler_name_hash (this, false);
+ if (in_init_priority_hash)
+ {
+ struct symbol_priority_map in;
+ void **slot;
+ in.symbol = this;
+
+ slot = htab_find_slot (init_priority_hash, &in, NO_INSERT);
+ if (slot)
+ htab_clear_slot (init_priority_hash, slot);
+ }
+}
+
+
+/* Remove symbol from symbol table. */
+
+void
+symtab_node::remove (void)
+{
+ if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
+ cnode->remove ();
+ else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
+ vnode->remove ();
+}
+
/* Add NEW_ to the same comdat group that OLD is in. */
void
-symtab_add_to_same_comdat_group (symtab_node *new_node,
- symtab_node *old_node)
+symtab_node::add_to_same_comdat_group (symtab_node *old_node)
{
gcc_assert (old_node->get_comdat_group ());
- gcc_assert (!new_node->same_comdat_group);
- gcc_assert (new_node != old_node);
+ gcc_assert (!same_comdat_group);
+ gcc_assert (this != old_node);
- new_node->set_comdat_group (old_node->get_comdat_group ());
- new_node->same_comdat_group = old_node;
+ set_comdat_group (old_node->get_comdat_group ());
+ same_comdat_group = old_node;
if (!old_node->same_comdat_group)
- old_node->same_comdat_group = new_node;
+ old_node->same_comdat_group = this;
else
{
symtab_node *n;
@@ -480,19 +509,19 @@ symtab_add_to_same_comdat_group (symtab_node *new_node,
n->same_comdat_group != old_node;
n = n->same_comdat_group)
;
- n->same_comdat_group = new_node;
+ n->same_comdat_group = this;
}
}
/* Dissolve the same_comdat_group list in which NODE resides. */
void
-symtab_dissolve_same_comdat_group_list (symtab_node *node)
+symtab_node::dissolve_same_comdat_group_list (void)
{
- symtab_node *n = node;
+ symtab_node *n = this;
symtab_node *next;
- if (!node->same_comdat_group)
+ if (!same_comdat_group)
return;
do
{
@@ -504,7 +533,7 @@ symtab_dissolve_same_comdat_group_list (symtab_node *node)
n->set_comdat_group (NULL);
n = next;
}
- while (n != node);
+ while (n != this);
}
/* Return printable assembler name of NODE.
@@ -609,7 +638,7 @@ symtab_node::maybe_add_reference (tree val, enum ipa_ref_use use_type,
if (val && (TREE_CODE (val) == FUNCTION_DECL
|| TREE_CODE (val) == VAR_DECL))
{
- symtab_node *referred = symtab_get_node (val);
+ symtab_node *referred = symtab_node::get (val);
gcc_checking_assert (referred);
return add_reference (referred, use_type, stmt);
}
@@ -825,184 +854,172 @@ symtab_node::iterate_direct_aliases (unsigned i, struct ipa_ref *&ref)
return ref;
}
-
static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
-/* Dump base fields of symtab nodes. Not to be used directly. */
+/* Dump base fields of symtab nodes to F. Not to be used directly. */
void
-dump_symtab_base (FILE *f, symtab_node *node)
+symtab_node::dump_base (FILE *f)
{
static const char * const visibility_types[] = {
"default", "protected", "hidden", "internal"
};
- fprintf (f, "%s/%i (%s)",
- node->asm_name (),
- node->order,
- node->name ());
- dump_addr (f, " @", (void *)node);
- fprintf (f, "\n Type: %s", symtab_type_names[node->type]);
+ fprintf (f, "%s/%i (%s)", asm_name (), order, name ());
+ dump_addr (f, " @", (void *)this);
+ fprintf (f, "\n Type: %s", symtab_type_names[type]);
- if (node->definition)
+ if (definition)
fprintf (f, " definition");
- if (node->analyzed)
+ if (analyzed)
fprintf (f, " analyzed");
- if (node->alias)
+ if (alias)
fprintf (f, " alias");
- if (node->weakref)
+ if (weakref)
fprintf (f, " weakref");
- if (node->cpp_implicit_alias)
+ if (cpp_implicit_alias)
fprintf (f, " cpp_implicit_alias");
- if (node->alias_target)
+ if (alias_target)
fprintf (f, " target:%s",
- DECL_P (node->alias_target)
+ DECL_P (alias_target)
? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
- (node->alias_target))
- : IDENTIFIER_POINTER (node->alias_target));
- if (node->body_removed)
+ (alias_target))
+ : IDENTIFIER_POINTER (alias_target));
+ if (body_removed)
fprintf (f, "\n Body removed by symtab_remove_unreachable_nodes");
fprintf (f, "\n Visibility:");
- if (node->in_other_partition)
+ if (in_other_partition)
fprintf (f, " in_other_partition");
- if (node->used_from_other_partition)
+ if (used_from_other_partition)
fprintf (f, " used_from_other_partition");
- if (node->force_output)
+ if (force_output)
fprintf (f, " force_output");
- if (node->forced_by_abi)
+ if (forced_by_abi)
fprintf (f, " forced_by_abi");
- if (node->externally_visible)
+ if (externally_visible)
fprintf (f, " externally_visible");
- if (node->resolution != LDPR_UNKNOWN)
+ if (resolution != LDPR_UNKNOWN)
fprintf (f, " %s",
- ld_plugin_symbol_resolution_names[(int)node->resolution]);
- if (TREE_ASM_WRITTEN (node->decl))
+ ld_plugin_symbol_resolution_names[(int)resolution]);
+ if (TREE_ASM_WRITTEN (decl))
fprintf (f, " asm_written");
- if (DECL_EXTERNAL (node->decl))
+ if (DECL_EXTERNAL (decl))
fprintf (f, " external");
- if (TREE_PUBLIC (node->decl))
+ if (TREE_PUBLIC (decl))
fprintf (f, " public");
- if (DECL_COMMON (node->decl))
+ if (DECL_COMMON (decl))
fprintf (f, " common");
- if (DECL_WEAK (node->decl))
+ if (DECL_WEAK (decl))
fprintf (f, " weak");
- if (DECL_DLLIMPORT_P (node->decl))
+ if (DECL_DLLIMPORT_P (decl))
fprintf (f, " dll_import");
- if (DECL_COMDAT (node->decl))
+ if (DECL_COMDAT (decl))
fprintf (f, " comdat");
- if (node->get_comdat_group ())
+ if (get_comdat_group ())
fprintf (f, " comdat_group:%s",
- IDENTIFIER_POINTER (node->get_comdat_group_id ()));
- if (DECL_ONE_ONLY (node->decl))
+ IDENTIFIER_POINTER (get_comdat_group_id ()));
+ if (DECL_ONE_ONLY (decl))
fprintf (f, " one_only");
- if (node->get_section ())
+ if (get_section ())
fprintf (f, " section:%s",
- node->get_section ());
- if (node->implicit_section)
+ get_section ());
+ if (implicit_section)
fprintf (f," (implicit_section)");
- if (DECL_VISIBILITY_SPECIFIED (node->decl))
+ if (DECL_VISIBILITY_SPECIFIED (decl))
fprintf (f, " visibility_specified");
- if (DECL_VISIBILITY (node->decl))
+ if (DECL_VISIBILITY (decl))
fprintf (f, " visibility:%s",
- visibility_types [DECL_VISIBILITY (node->decl)]);
- if (DECL_VIRTUAL_P (node->decl))
+ visibility_types [DECL_VISIBILITY (decl)]);
+ if (DECL_VIRTUAL_P (decl))
fprintf (f, " virtual");
- if (DECL_ARTIFICIAL (node->decl))
+ if (DECL_ARTIFICIAL (decl))
fprintf (f, " artificial");
- if (TREE_CODE (node->decl) == FUNCTION_DECL)
+ if (TREE_CODE (decl) == FUNCTION_DECL)
{
- if (DECL_STATIC_CONSTRUCTOR (node->decl))
+ if (DECL_STATIC_CONSTRUCTOR (decl))
fprintf (f, " constructor");
- if (DECL_STATIC_DESTRUCTOR (node->decl))
+ if (DECL_STATIC_DESTRUCTOR (decl))
fprintf (f, " destructor");
}
fprintf (f, "\n");
- if (node->same_comdat_group)
+ if (same_comdat_group)
fprintf (f, " Same comdat group as: %s/%i\n",
- node->same_comdat_group->asm_name (),
- node->same_comdat_group->order);
- if (node->next_sharing_asm_name)
+ same_comdat_group->asm_name (),
+ same_comdat_group->order);
+ if (next_sharing_asm_name)
fprintf (f, " next sharing asm name: %i\n",
- node->next_sharing_asm_name->order);
- if (node->previous_sharing_asm_name)
+ next_sharing_asm_name->order);
+ if (previous_sharing_asm_name)
fprintf (f, " previous sharing asm name: %i\n",
- node->previous_sharing_asm_name->order);
+ previous_sharing_asm_name->order);
- if (node->address_taken)
+ if (address_taken)
fprintf (f, " Address is taken.\n");
- if (node->aux)
+ if (aux)
{
fprintf (f, " Aux:");
- dump_addr (f, " @", (void *)node->aux);
+ dump_addr (f, " @", (void *)aux);
}
fprintf (f, " References: ");
- node->dump_references (f);
+ dump_references (f);
fprintf (f, " Referring: ");
- node->dump_referring (f);
- if (node->lto_file_data)
+ dump_referring (f);
+ if (lto_file_data)
fprintf (f, " Read from file: %s\n",
- node->lto_file_data->file_name);
+ lto_file_data->file_name);
}
-/* Dump symtab node. */
+/* Dump symtab node to F. */
void
-dump_symtab_node (FILE *f, symtab_node *node)
+symtab_node::dump (FILE *f)
{
- if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
- dump_cgraph_node (f, cnode);
- else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
- dump_varpool_node (f, vnode);
+ if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
+ cnode->dump (f);
+ else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
+ vnode->dump (f);
}
-/* Dump symbol table. */
+/* Dump symbol table to F. */
void
-dump_symtab (FILE *f)
+symtab_node::dump_table (FILE *f)
{
symtab_node *node;
fprintf (f, "Symbol table:\n\n");
FOR_EACH_SYMBOL (node)
- dump_symtab_node (f, node);
+ node->dump (f);
}
/* Dump symtab node NODE to stderr. */
DEBUG_FUNCTION void
-debug_symtab_node (symtab_node *node)
-{
- dump_symtab_node (stderr, node);
-}
-
-/* Dump symbol table to stderr. */
-
-DEBUG_FUNCTION void
-debug_symtab (void)
+symtab_node::debug (void)
{
- dump_symtab (stderr);
+ dump (stderr);
}
/* Verify common part of symtab nodes. */
DEBUG_FUNCTION bool
-verify_symtab_base (symtab_node *node)
+symtab_node::verify_base (void)
{
bool error_found = false;
symtab_node *hashed_node;
- if (is_a <cgraph_node *> (node))
+ if (is_a <cgraph_node *> (this))
{
- if (TREE_CODE (node->decl) != FUNCTION_DECL)
+ if (TREE_CODE (decl) != FUNCTION_DECL)
{
error ("function symbol is not function");
error_found = true;
}
}
- else if (is_a <varpool_node *> (node))
+ else if (is_a <varpool_node *> (this))
{
- if (TREE_CODE (node->decl) != VAR_DECL)
+ if (TREE_CODE (decl) != VAR_DECL)
{
error ("variable symbol is not variable");
error_found = true;
@@ -1016,17 +1033,16 @@ verify_symtab_base (symtab_node *node)
if (cgraph_state != CGRAPH_LTO_STREAMING)
{
- hashed_node = symtab_get_node (node->decl);
+ hashed_node = symtab_node::get (decl);
if (!hashed_node)
{
error ("node not found node->decl->decl_with_vis.symtab_node");
error_found = true;
}
- if (hashed_node != node
- && (!is_a <cgraph_node *> (node)
- || !dyn_cast <cgraph_node *> (node)->clone_of
- || dyn_cast <cgraph_node *> (node)->clone_of->decl
- != node->decl))
+ if (hashed_node != this
+ && (!is_a <cgraph_node *> (this)
+ || !dyn_cast <cgraph_node *> (this)->clone_of
+ || dyn_cast <cgraph_node *> (this)->clone_of->decl != decl))
{
error ("node differs from node->decl->decl_with_vis.symtab_node");
error_found = true;
@@ -1034,7 +1050,7 @@ verify_symtab_base (symtab_node *node)
}
if (assembler_name_hash)
{
- hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->decl));
+ hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
if (hashed_node && hashed_node->previous_sharing_asm_name)
{
error ("assembler name hash list corrupted");
@@ -1042,55 +1058,54 @@ verify_symtab_base (symtab_node *node)
}
while (hashed_node)
{
- if (hashed_node == node)
+ if (hashed_node == this)
break;
hashed_node = hashed_node->next_sharing_asm_name;
}
if (!hashed_node
- && !(is_a <varpool_node *> (node)
- || DECL_HARD_REGISTER (node->decl)))
+ && !(is_a <varpool_node *> (this)
+ || DECL_HARD_REGISTER (decl)))
{
error ("node not found in symtab assembler name hash");
error_found = true;
}
}
- if (node->previous_sharing_asm_name
- && node->previous_sharing_asm_name->next_sharing_asm_name != node)
+ if (previous_sharing_asm_name
+ && previous_sharing_asm_name->next_sharing_asm_name != this)
{
error ("double linked list of assembler names corrupted");
error_found = true;
}
- if (node->analyzed && !node->definition)
+ if (analyzed && !definition)
{
error ("node is analyzed byt it is not a definition");
error_found = true;
}
- if (node->cpp_implicit_alias && !node->alias)
+ if (cpp_implicit_alias && !alias)
{
error ("node is alias but not implicit alias");
error_found = true;
}
- if (node->alias && !node->definition
- && !node->weakref)
+ if (alias && !definition && !weakref)
{
error ("node is alias but not definition");
error_found = true;
}
- if (node->weakref && !node->alias)
+ if (weakref && !alias)
{
error ("node is weakref but not an alias");
error_found = true;
}
- if (node->same_comdat_group)
+ if (same_comdat_group)
{
- symtab_node *n = node->same_comdat_group;
+ symtab_node *n = same_comdat_group;
if (!n->get_comdat_group ())
{
error ("node is in same_comdat_group list but has no comdat_group");
error_found = true;
}
- if (n->get_comdat_group () != node->get_comdat_group ())
+ if (n->get_comdat_group () != get_comdat_group ())
{
error ("same_comdat_group list across different groups");
error_found = true;
@@ -1100,12 +1115,12 @@ verify_symtab_base (symtab_node *node)
error ("Node has same_comdat_group but it is not a definition");
error_found = true;
}
- if (n->type != node->type)
+ if (n->type != type)
{
error ("mixing different types of symbol in same comdat groups is not supported");
error_found = true;
}
- if (n == node)
+ if (n == this)
{
error ("node is alone in a comdat group");
error_found = true;
@@ -1120,14 +1135,14 @@ verify_symtab_base (symtab_node *node)
}
n = n->same_comdat_group;
}
- while (n != node);
- if (symtab_comdat_local_p (node))
+ while (n != this);
+ if (comdat_local_p ())
{
struct ipa_ref *ref = NULL;
- for (int i = 0; node->iterate_referring (i, ref); ++i)
+ for (int i = 0; iterate_referring (i, ref); ++i)
{
- if (!symtab_in_same_comdat_p (ref->referring, node))
+ if (!in_same_comdat_group_p (ref->referring))
{
error ("comdat-local symbol referred to by %s outside its "
"comdat",
@@ -1137,35 +1152,35 @@ verify_symtab_base (symtab_node *node)
}
}
}
- if (node->implicit_section && !node->get_section ())
+ if (implicit_section && !get_section ())
{
error ("implicit_section flag is set but section isn't");
error_found = true;
}
- if (node->get_section () && node->get_comdat_group ()
- && !node->implicit_section)
+ if (get_section () && get_comdat_group ()
+ && !implicit_section)
{
error ("Both section and comdat group is set");
error_found = true;
}
/* TODO: Add string table for sections, so we do not keep holding duplicated
strings. */
- if (node->alias && node->definition
- && node->get_section () != symtab_alias_target (node)->get_section ()
- && (!node->get_section()
- || !symtab_alias_target (node)->get_section ()
- || strcmp (node->get_section(),
- symtab_alias_target (node)->get_section ())))
+ if (alias && definition
+ && get_section () != get_alias_target ()->get_section ()
+ && (!get_section()
+ || !get_alias_target ()->get_section ()
+ || strcmp (get_section(),
+ get_alias_target ()->get_section ())))
{
error ("Alias and target's section differs");
- dump_symtab_node (stderr, symtab_alias_target (node));
+ get_alias_target ()->dump (stderr);
error_found = true;
}
- if (node->alias && node->definition
- && node->get_comdat_group () != symtab_alias_target (node)->get_comdat_group ())
+ if (alias && definition
+ && get_comdat_group () != get_alias_target ()->get_comdat_group ())
{
error ("Alias and target's comdat groups differs");
- dump_symtab_node (stderr, symtab_alias_target (node));
+ get_alias_target ()->dump (stderr);
error_found = true;
}
@@ -1175,19 +1190,19 @@ verify_symtab_base (symtab_node *node)
/* Verify consistency of NODE. */
DEBUG_FUNCTION void
-verify_symtab_node (symtab_node *node)
+symtab_node::verify (void)
{
if (seen_error ())
return;
timevar_push (TV_CGRAPH_VERIFY);
- if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
- verify_cgraph_node (cnode);
+ if (cgraph_node *node = dyn_cast <cgraph_node *> (this))
+ node->verify_node ();
else
- if (verify_symtab_base (node))
+ if (verify_base ())
{
- dump_symtab_node (stderr, node);
- internal_error ("verify_symtab_node failed");
+ debug ();
+ internal_error ("symtab_node::verify failed");
}
timevar_pop (TV_CGRAPH_VERIFY);
}
@@ -1195,14 +1210,14 @@ verify_symtab_node (symtab_node *node)
/* Verify symbol table for internal consistency. */
DEBUG_FUNCTION void
-verify_symtab (void)
+symtab_node::verify_symtab_nodes (void)
{
symtab_node *node;
hash_map<tree, symtab_node *> comdat_head_map (251);
FOR_EACH_SYMBOL (node)
{
- verify_symtab_node (node);
+ node->verify ();
if (node->get_comdat_group ())
{
symtab_node **entry, *s;
@@ -1217,31 +1232,19 @@ verify_symtab (void)
if (!s || s == *entry)
{
error ("Two symbols with same comdat_group are not linked by the same_comdat_group list.");
- dump_symtab_node (stderr, *entry);
- dump_symtab_node (stderr, node);
- internal_error ("verify_symtab failed");
+ (*entry)->debug ();
+ node->debug ();
+ internal_error ("symtab_node::verify failed");
}
}
}
}
-/* Return true when RESOLUTION indicate that linker will use
- the symbol from non-LTO object files. */
-
-bool
-resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
-{
- return (resolution == LDPR_PREVAILING_DEF
- || resolution == LDPR_PREEMPTED_REG
- || resolution == LDPR_RESOLVED_EXEC
- || resolution == LDPR_RESOLVED_DYN);
-}
-
-/* Return true when NODE is known to be used from other (non-LTO) object file.
- Known only when doing LTO via linker plugin. */
+/* Return true when NODE is known to be used from other (non-LTO)
+ object file. Known only when doing LTO via linker plugin. */
bool
-symtab_used_from_object_file_p (symtab_node *node)
+symtab_node::used_from_object_file_p_worker (symtab_node *node)
{
if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl))
return false;
@@ -1250,11 +1253,21 @@ symtab_used_from_object_file_p (symtab_node *node)
return false;
}
+
+/* Return true when symtab_node is known to be used from other (non-LTO)
+ object file. Known only when doing LTO via linker plugin. */
+
+bool
+symtab_node::used_from_object_file_p (void)
+{
+ return symtab_node::used_from_object_file_p_worker (this);
+}
+
/* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
but other code such as notice_global_symbol generates rtl. */
void
-symtab_make_decl_local (tree decl)
+symtab_node::make_decl_local (void)
{
rtx rtl, symbol;
@@ -1289,31 +1302,20 @@ symtab_make_decl_local (tree decl)
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}
-/* Return availability of NODE. */
-
-enum availability
-symtab_node_availability (symtab_node *node)
-{
- if (is_a <cgraph_node *> (node))
- return cgraph_function_body_availability (cgraph (node));
- else
- return cgraph_variable_initializer_availability (varpool (node));
-}
-
-/* Given NODE, walk the alias chain to return the symbol NODE is alias of.
+/* Walk the alias chain to return the symbol NODE is alias of.
If NODE is not an alias, return NODE.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
symtab_node *
-symtab_alias_ultimate_target (symtab_node *node, enum availability *availability)
+symtab_node::ultimate_alias_target (enum availability *availability)
{
bool weakref_p = false;
- if (!node->alias)
+ if (!alias)
{
if (availability)
- *availability = symtab_node_availability (node);
- return node;
+ *availability = get_availability ();
+ return this;
}
/* To determine visibility of the target, we follow ELF semantic of aliases.
@@ -1332,16 +1334,18 @@ symtab_alias_ultimate_target (symtab_node *node, enum availability *availability
if (availability)
{
- weakref_p = node->weakref;
+ weakref_p = weakref;
if (!weakref_p)
- *availability = symtab_node_availability (node);
+ *availability = get_availability ();
else
*availability = AVAIL_LOCAL;
}
+
+ symtab_node *node = this;
while (node)
{
if (node->alias && node->analyzed)
- node = symtab_alias_target (node);
+ node = node->get_alias_target ();
else
{
if (!availability)
@@ -1350,7 +1354,7 @@ symtab_alias_ultimate_target (symtab_node *node, enum availability *availability
{
if (weakref_p)
{
- enum availability a = symtab_node_availability (node);
+ enum availability a = node->get_availability ();
if (a < *availability)
*availability = a;
}
@@ -1361,7 +1365,7 @@ symtab_alias_ultimate_target (symtab_node *node, enum availability *availability
}
if (node && availability && weakref_p)
{
- enum availability a = symtab_node_availability (node);
+ enum availability a = node->get_availability ();
if (a < *availability)
*availability = a;
weakref_p = node->weakref;
@@ -1380,61 +1384,41 @@ symtab_alias_ultimate_target (symtab_node *node, enum availability *availability
copy the visibility from the target to get things right. */
void
-fixup_same_cpp_alias_visibility (symtab_node *node, symtab_node *target)
+symtab_node::fixup_same_cpp_alias_visibility (symtab_node *target)
{
- if (is_a <cgraph_node *> (node))
+ if (is_a <cgraph_node *> (this))
{
- DECL_DECLARED_INLINE_P (node->decl)
+ DECL_DECLARED_INLINE_P (decl)
= DECL_DECLARED_INLINE_P (target->decl);
- DECL_DISREGARD_INLINE_LIMITS (node->decl)
+ DECL_DISREGARD_INLINE_LIMITS (decl)
= DECL_DISREGARD_INLINE_LIMITS (target->decl);
}
/* FIXME: It is not really clear why those flags should not be copied for
functions, too. */
else
{
- DECL_WEAK (node->decl) = DECL_WEAK (target->decl);
- DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl);
- DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (target->decl);
+ DECL_WEAK (decl) = DECL_WEAK (target->decl);
+ DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
+ DECL_VISIBILITY (decl) = DECL_VISIBILITY (target->decl);
}
- DECL_VIRTUAL_P (node->decl) = DECL_VIRTUAL_P (target->decl);
- if (TREE_PUBLIC (node->decl))
+ DECL_VIRTUAL_P (decl) = DECL_VIRTUAL_P (target->decl);
+ if (TREE_PUBLIC (decl))
{
tree group;
- DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl);
- DECL_COMDAT (node->decl) = DECL_COMDAT (target->decl);
+ DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
+ DECL_COMDAT (decl) = DECL_COMDAT (target->decl);
group = target->get_comdat_group ();
- node->set_comdat_group (group);
- if (group
- && !node->same_comdat_group)
- symtab_add_to_same_comdat_group (node, target);
+ set_comdat_group (group);
+ if (group && !same_comdat_group)
+ add_to_same_comdat_group (target);
}
- node->externally_visible = target->externally_visible;
-}
-
-/* Hash sections by their names. */
-
-static hashval_t
-hash_section_hash_entry (const void *p)
-{
- const section_hash_entry *n = (const section_hash_entry *) p;
- return htab_hash_string (n->name);
-}
-
-/* Return true if section P1 name equals to P2. */
-
-static int
-eq_sections (const void *p1, const void *p2)
-{
- const section_hash_entry *n1 = (const section_hash_entry *) p1;
- const char *name = (const char *)p2;
- return n1->name == name || !strcmp (n1->name, name);
+ externally_visible = target->externally_visible;
}
/* Set section, do not recurse into aliases.
When one wants to change section of symbol and its aliases,
- use set_section */
+ use set_section. */
void
symtab_node::set_section_for_node (const char *section)
@@ -1485,8 +1469,8 @@ symtab_node::set_section_for_node (const char *section)
/* Worker for set_section. */
-static bool
-set_section_1 (struct symtab_node *n, void *s)
+bool
+symtab_node::set_section (symtab_node *n, void *s)
{
n->set_section_for_node ((char *)s);
return false;
@@ -1498,7 +1482,8 @@ void
symtab_node::set_section (const char *section)
{
gcc_assert (!this->alias);
- symtab_for_node_and_aliases (this, set_section_1, const_cast<char *>(section), true);
+ call_for_symbol_and_aliases
+ (symtab_node::set_section, const_cast<char *>(section), true);
}
/* Return the initialization priority. */
@@ -1516,6 +1501,17 @@ symtab_node::get_init_priority ()
return h ? h->init : DEFAULT_INIT_PRIORITY;
}
+/* Return availability of NODE. */
+enum availability symtab_node::get_availability (void)
+{
+ if (is_a <cgraph_node *> (this))
+ return dyn_cast <cgraph_node *> (this)->get_availability ();
+ else
+ return cgraph_variable_initializer_availability
+ (dyn_cast <varpool_node *> (this));
+}
+
+
/* Return the finalization priority. */
priority_type
@@ -1553,14 +1549,14 @@ symbol_priority_map_hash (const void *item)
DECL. If there is no previous priority information, a freshly
allocated structure is returned. */
-static struct symbol_priority_map *
-symbol_priority_info (struct symtab_node *symbol)
+struct symbol_priority_map *
+symtab_node::priority_info (void)
{
struct symbol_priority_map in;
struct symbol_priority_map *h;
void **loc;
- in.symbol = symbol;
+ in.symbol = this;
if (!init_priority_hash)
init_priority_hash = htab_create_ggc (512, symbol_priority_map_hash,
symbol_priority_map_eq, 0);
@@ -1571,10 +1567,10 @@ symbol_priority_info (struct symtab_node *symbol)
{
h = ggc_cleared_alloc<symbol_priority_map> ();
*loc = h;
- h->symbol = symbol;
+ h->symbol = this;
h->init = DEFAULT_INIT_PRIORITY;
h->fini = DEFAULT_INIT_PRIORITY;
- symbol->in_init_priority_hash = true;
+ in_init_priority_hash = true;
}
return h;
@@ -1595,7 +1591,7 @@ symtab_node::set_init_priority (priority_type priority)
gcc_assert (get_init_priority() == priority);
return;
}
- h = symbol_priority_info (this);
+ h = priority_info ();
h->init = priority;
}
@@ -1613,123 +1609,119 @@ cgraph_node::set_fini_priority (priority_type priority)
gcc_assert (get_fini_priority() == priority);
return;
}
- h = symbol_priority_info (this);
+ h = priority_info ();
h->fini = priority;
}
/* Worker for symtab_resolve_alias. */
-static bool
-set_implicit_section (struct symtab_node *n, void *data ATTRIBUTE_UNUSED)
+bool
+symtab_node::set_implicit_section (symtab_node *n,
+ void *data ATTRIBUTE_UNUSED)
{
n->implicit_section = true;
return false;
}
-/* Add reference recording that NODE is alias of TARGET.
+/* Add reference recording that symtab node is alias of TARGET.
The function can fail in the case of aliasing cycles; in this case
it returns false. */
bool
-symtab_resolve_alias (symtab_node *node, symtab_node *target)
+symtab_node::resolve_alias (symtab_node *target)
{
symtab_node *n;
- gcc_assert (!node->analyzed
- && !vec_safe_length (node->ref_list.references));
+ gcc_assert (!analyzed && !vec_safe_length (ref_list.references));
/* Never let cycles to creep into the symbol table alias references;
those will make alias walkers to be infinite. */
for (n = target; n && n->alias;
- n = n->analyzed ? symtab_alias_target (n) : NULL)
- if (n == node)
+ n = n->analyzed ? n->get_alias_target () : NULL)
+ if (n == this)
{
- if (is_a <cgraph_node *> (node))
- error ("function %q+D part of alias cycle", node->decl);
- else if (is_a <varpool_node *> (node))
- error ("variable %q+D part of alias cycle", node->decl);
+ if (is_a <cgraph_node *> (this))
+ error ("function %q+D part of alias cycle", decl);
+ else if (is_a <varpool_node *> (this))
+ error ("variable %q+D part of alias cycle", decl);
else
gcc_unreachable ();
- node->alias = false;
+ alias = false;
return false;
}
/* "analyze" the node - i.e. mark the reference. */
- node->definition = true;
- node->alias = true;
- node->analyzed = true;
- node->add_reference (target, IPA_REF_ALIAS, NULL);
+ definition = true;
+ alias = true;
+ analyzed = true;
+ add_reference (target, IPA_REF_ALIAS, NULL);
/* Add alias into the comdat group of its target unless it is already there. */
- if (node->same_comdat_group)
- symtab_remove_from_same_comdat_group (node);
- node->set_comdat_group (NULL);
+ if (same_comdat_group)
+ remove_from_same_comdat_group ();
+ set_comdat_group (NULL);
if (target->get_comdat_group ())
- symtab_add_to_same_comdat_group (node, target);
+ add_to_same_comdat_group (target);
- if ((node->get_section () != target->get_section ()
- || target->get_comdat_group ())
- && node->get_section () && !node->implicit_section)
+ if ((get_section () != target->get_section ()
+ || target->get_comdat_group ()) && get_section () && !implicit_section)
{
- error ("section of alias %q+D must match section of its target",
- node->decl);
+ error ("section of alias %q+D must match section of its target", decl);
}
- symtab_for_node_and_aliases (node, set_section_1,
- const_cast<char *>(target->get_section ()), true);
+ call_for_symbol_and_aliases (symtab_node::set_section,
+ const_cast<char *>(target->get_section ()), true);
if (target->implicit_section)
- symtab_for_node_and_aliases (node,
- set_implicit_section, NULL, true);
+ call_for_symbol_and_aliases (set_implicit_section, NULL, true);
/* Alias targets become redundant after alias is resolved into an reference.
We do not want to keep it around or we would have to mind updating them
when renaming symbols. */
- node->alias_target = NULL;
+ alias_target = NULL;
- if (node->cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION)
- fixup_same_cpp_alias_visibility (node, target);
+ if (cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION)
+ fixup_same_cpp_alias_visibility (target);
/* If alias has address taken, so does the target. */
- if (node->address_taken)
- symtab_alias_ultimate_target (target, NULL)->address_taken = true;
+ if (address_taken)
+ target->ultimate_alias_target ()->address_taken = true;
return true;
}
-/* Call calback on NODE and aliases associated to NODE.
+/* Call calback on symtab node and aliases associated to this node.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */
bool
-symtab_for_node_and_aliases (symtab_node *node,
- bool (*callback) (symtab_node *, void *),
- void *data,
- bool include_overwritable)
+symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
+ void *),
+ void *data, bool include_overwritable)
{
int i;
struct ipa_ref *ref;
- if (callback (node, data))
+ if (callback (this, data))
return true;
- for (i = 0; node->iterate_referring (i, ref); i++)
+ for (i = 0; iterate_referring (i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
{
symtab_node *alias = ref->referring;
if (include_overwritable
- || symtab_node_availability (alias) > AVAIL_OVERWRITABLE)
- if (symtab_for_node_and_aliases (alias, callback, data,
- include_overwritable))
+ || alias->get_availability () > AVAIL_INTERPOSABLE)
+ if (alias->call_for_symbol_and_aliases (callback, data,
+ include_overwritable))
return true;
}
return false;
}
-/* Worker searching nonoverwritable alias. */
+/* Worker searching noninterposable alias. */
-static bool
-symtab_nonoverwritable_alias_1 (symtab_node *node, void *data)
+bool
+symtab_node::noninterposable_alias (symtab_node *node, void *data)
{
if (decl_binds_to_current_def_p (node->decl))
{
- symtab_node *fn = symtab_alias_ultimate_target (node);
+ symtab_node *fn = node->ultimate_alias_target ();
/* Ensure that the alias is well formed this may not be the case
of user defined aliases and currently it is not always the case
@@ -1748,22 +1740,22 @@ symtab_nonoverwritable_alias_1 (symtab_node *node, void *data)
return false;
}
-/* If NODE can not be overwriten by static or dynamic linker to point to different
- definition, return NODE. Otherwise look for alias with such property and if
- none exists, introduce new one. */
+/* If node can not be overwriten by static or dynamic linker to point to
+ different definition, return NODE. Otherwise look for alias with such
+ property and if none exists, introduce new one. */
symtab_node *
-symtab_nonoverwritable_alias (symtab_node *node)
+symtab_node::noninterposable_alias (void)
{
tree new_decl;
symtab_node *new_node = NULL;
/* First try to look up existing alias or base object
(if that is already non-overwritable). */
- node = symtab_alias_ultimate_target (node, NULL);
+ symtab_node *node = ultimate_alias_target ();
gcc_assert (!node->alias && !node->weakref);
- symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
- (void *)&new_node, true);
+ node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias,
+ (void *)&new_node, true);
if (new_node)
return new_node;
#ifndef ASM_OUTPUT_DEF
@@ -1792,8 +1784,7 @@ symtab_nonoverwritable_alias (symtab_node *node)
{
DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
DECL_STATIC_DESTRUCTOR (new_decl) = 0;
- new_node = cgraph_create_function_alias
- (new_decl, node->decl);
+ new_node = cgraph_node::create_alias (new_decl, node->decl);
}
else
{
@@ -1801,76 +1792,76 @@ symtab_nonoverwritable_alias (symtab_node *node)
DECL_INITIAL (new_decl) = error_mark_node;
new_node = varpool_create_variable_alias (new_decl, node->decl);
}
- symtab_resolve_alias (new_node, node);
+ new_node->resolve_alias (node);
gcc_assert (decl_binds_to_current_def_p (new_decl)
&& targetm.binds_local_p (new_decl));
return new_node;
}
-/* Return true if A and B represents semantically equivalent symbols. */
+/* Return true if symtab node and TARGET represents
+ semantically equivalent symbols. */
bool
-symtab_semantically_equivalent_p (symtab_node *a,
- symtab_node *b)
+symtab_node::semantically_equivalent_p (symtab_node *target)
{
enum availability avail;
symtab_node *ba;
symtab_node *bb;
/* Equivalent functions are equivalent. */
- if (a->decl == b->decl)
+ if (decl == target->decl)
return true;
/* If symbol is not overwritable by different implementation,
walk to the base object it defines. */
- ba = symtab_alias_ultimate_target (a, &avail);
+ ba = ultimate_alias_target (&avail);
if (avail >= AVAIL_AVAILABLE)
{
- if (ba == b)
+ if (target == ba)
return true;
}
else
- ba = a;
- bb = symtab_alias_ultimate_target (b, &avail);
+ ba = this;
+ bb = target->ultimate_alias_target (&avail);
if (avail >= AVAIL_AVAILABLE)
{
- if (a == bb)
+ if (this == bb)
return true;
}
else
- bb = b;
+ bb = target;
return bb == ba;
}
-/* Classify symbol NODE for partitioning. */
+/* Classify symbol symtab node for partitioning. */
enum symbol_partitioning_class
-symtab_get_symbol_partitioning_class (symtab_node *node)
+symtab_node::get_partitioning_class (void)
{
/* Inline clones are always duplicated.
This include external delcarations. */
- cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
- if (DECL_ABSTRACT (node->decl))
+ if (DECL_ABSTRACT (decl))
return SYMBOL_EXTERNAL;
if (cnode && cnode->global.inlined_to)
return SYMBOL_DUPLICATE;
/* Weakref aliases are always duplicated. */
- if (node->weakref)
+ if (weakref)
return SYMBOL_DUPLICATE;
/* External declarations are external. */
- if (DECL_EXTERNAL (node->decl))
+ if (DECL_EXTERNAL (decl))
return SYMBOL_EXTERNAL;
- if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
+ if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
{
/* Constant pool references use local symbol names that can not
be promoted global. We should never put into a constant pool
objects that can not be duplicated across partitions. */
- if (DECL_IN_CONSTANT_POOL (node->decl))
+ if (DECL_IN_CONSTANT_POOL (decl))
return SYMBOL_DUPLICATE;
gcc_checking_assert (vnode->definition);
}
@@ -1878,15 +1869,15 @@ symtab_get_symbol_partitioning_class (symtab_node *node)
Handle them as external; compute_ltrans_boundary take care to make
proper things to happen (i.e. to make them appear in the boundary but
with body streamed, so clone can me materialized). */
- else if (!cgraph (node)->definition)
+ else if (!dyn_cast <cgraph_node *> (this)->definition)
return SYMBOL_EXTERNAL;
/* Linker discardable symbols are duplicated to every use unless they are
keyed. */
- if (DECL_ONE_ONLY (node->decl)
- && !node->force_output
- && !node->forced_by_abi
- && !symtab_used_from_object_file_p (node))
+ if (DECL_ONE_ONLY (decl)
+ && !force_output
+ && !forced_by_abi
+ && !used_from_object_file_p ())
return SYMBOL_DUPLICATE;
return SYMBOL_PARTITION;
@@ -1902,7 +1893,7 @@ symtab_node::nonzero_address ()
{
if (this->analyzed)
{
- symtab_node *target = symtab_alias_ultimate_target (this);
+ symtab_node *target = ultimate_alias_target ();
if (target->alias && target->weakref)
return false;