aboutsummaryrefslogtreecommitdiff
path: root/gcc/symtab.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-08-02 16:38:15 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-08-02 14:38:15 +0000
commitaf15184ab60cc2c2caf47964734c3e123bc04f7c (patch)
tree1cccd5c74a32da024ef7d68be27022345b749039 /gcc/symtab.c
parent01e54ef86f407385b0f2bb7afb5748f0db31bce8 (diff)
downloadgcc-af15184ab60cc2c2caf47964734c3e123bc04f7c.zip
gcc-af15184ab60cc2c2caf47964734c3e123bc04f7c.tar.gz
gcc-af15184ab60cc2c2caf47964734c3e123bc04f7c.tar.bz2
cgraph.c (cgraph_function_body_availability): Do not check cgrpah flags.
* cgraph.c (cgraph_function_body_availability): Do not check cgrpah flags. * cgraph.h (symtab_for_node_and_aliases, symtab_nonoverwritable_alias, symtab_node_availability): Declare. * ipa.c (can_replace_by_local_alias): New. (function_and_variable_visibility): Use it. * symtab.c (symtab_for_node_and_aliases, symtab_nonoverwritable_alias_1, symtab_nonoverwritable_alias): New. Co-Authored-By: Martin Liska <marxin.liska@gmail.com> From-SVN: r201439
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r--gcc/symtab.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c
index d15881b..a86bf6b 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -1014,4 +1014,88 @@ symtab_resolve_alias (symtab_node node, symtab_node target)
symtab_alias_ultimate_target (target, NULL)->symbol.address_taken = true;
return true;
}
+
+/* Call calback on NODE and aliases associated to 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)
+{
+ int i;
+ struct ipa_ref *ref;
+
+ if (callback (node, data))
+ return true;
+ for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, 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))
+ return true;
+ }
+ return false;
+}
+
+/* Worker searching nonoverwritable alias. */
+
+static bool
+symtab_nonoverwritable_alias_1 (symtab_node node, void *data)
+{
+ if (decl_binds_to_current_def_p (node->symbol.decl))
+ {
+ *(symtab_node *)data = node;
+ return true;
+ }
+ 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. */
+
+symtab_node
+symtab_nonoverwritable_alias (symtab_node node)
+{
+ tree new_decl;
+ symtab_node new_node = NULL;
+ symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
+ (void *)&new_node, true);
+ if (new_node)
+ return new_node;
+
+ new_decl = copy_node (node->symbol.decl);
+ DECL_NAME (new_decl) = clone_function_name (node->symbol.decl, "localalias");
+ if (TREE_CODE (new_decl) == FUNCTION_DECL)
+ DECL_STRUCT_FUNCTION (new_decl) = NULL;
+ DECL_INITIAL (new_decl) = NULL;
+ SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
+ SET_DECL_RTL (new_decl, NULL);
+
+ /* Update the properties. */
+ DECL_EXTERNAL (new_decl) = 0;
+ if (DECL_ONE_ONLY (node->symbol.decl))
+ DECL_SECTION_NAME (new_decl) = NULL;
+ DECL_COMDAT_GROUP (new_decl) = 0;
+ TREE_PUBLIC (new_decl) = 0;
+ DECL_COMDAT (new_decl) = 0;
+ DECL_WEAK (new_decl) = 0;
+ DECL_VIRTUAL_P (new_decl) = 0;
+ if (TREE_CODE (new_decl) == FUNCTION_DECL)
+ {
+ DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
+ DECL_STATIC_DESTRUCTOR (new_decl) = 0;
+ new_node = (symtab_node) cgraph_create_function_alias (new_decl, node->symbol.decl);
+ }
+ else
+ new_node = (symtab_node) varpool_create_variable_alias (new_decl, node->symbol.decl);
+ symtab_resolve_alias (new_node, node);
+ return new_node;
+}
#include "gt-symtab.h"