xref: /dflybsd-src/contrib/gcc-8.0/gcc/symtab.c (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj /* Symbol table.
238fd1498Szrj    Copyright (C) 2012-2018 Free Software Foundation, Inc.
338fd1498Szrj    Contributed by Jan Hubicka
438fd1498Szrj 
538fd1498Szrj This file is part of GCC.
638fd1498Szrj 
738fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
838fd1498Szrj the terms of the GNU General Public License as published by the Free
938fd1498Szrj Software Foundation; either version 3, or (at your option) any later
1038fd1498Szrj version.
1138fd1498Szrj 
1238fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1338fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
1438fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1538fd1498Szrj for more details.
1638fd1498Szrj 
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3.  If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>.  */
2038fd1498Szrj 
2138fd1498Szrj #include "config.h"
2238fd1498Szrj #include "system.h"
2338fd1498Szrj #include "coretypes.h"
2438fd1498Szrj #include "backend.h"
2538fd1498Szrj #include "target.h"
2638fd1498Szrj #include "rtl.h"
2738fd1498Szrj #include "tree.h"
2838fd1498Szrj #include "gimple.h"
2938fd1498Szrj #include "timevar.h"
3038fd1498Szrj #include "cgraph.h"
3138fd1498Szrj #include "lto-streamer.h"
3238fd1498Szrj #include "print-tree.h"
3338fd1498Szrj #include "varasm.h"
3438fd1498Szrj #include "langhooks.h"
3538fd1498Szrj #include "output.h"
3638fd1498Szrj #include "ipa-utils.h"
3738fd1498Szrj #include "calls.h"
3838fd1498Szrj #include "stringpool.h"
3938fd1498Szrj #include "attribs.h"
4038fd1498Szrj #include "builtins.h"
4138fd1498Szrj 
4238fd1498Szrj static const char *ipa_ref_use_name[] = {"read","write","addr","alias","chkp"};
4338fd1498Szrj 
4438fd1498Szrj const char * const ld_plugin_symbol_resolution_names[]=
4538fd1498Szrj {
4638fd1498Szrj   "",
4738fd1498Szrj   "undef",
4838fd1498Szrj   "prevailing_def",
4938fd1498Szrj   "prevailing_def_ironly",
5038fd1498Szrj   "preempted_reg",
5138fd1498Szrj   "preempted_ir",
5238fd1498Szrj   "resolved_ir",
5338fd1498Szrj   "resolved_exec",
5438fd1498Szrj   "resolved_dyn",
5538fd1498Szrj   "prevailing_def_ironly_exp"
5638fd1498Szrj };
5738fd1498Szrj 
5838fd1498Szrj /* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at ALIAS
5938fd1498Szrj    until we find an identifier that is not itself a transparent alias.  */
6038fd1498Szrj 
6138fd1498Szrj static inline tree
ultimate_transparent_alias_target(tree alias)6238fd1498Szrj ultimate_transparent_alias_target (tree alias)
6338fd1498Szrj {
6438fd1498Szrj   tree target = alias;
6538fd1498Szrj 
6638fd1498Szrj   while (IDENTIFIER_TRANSPARENT_ALIAS (target))
6738fd1498Szrj     {
6838fd1498Szrj       gcc_checking_assert (TREE_CHAIN (target));
6938fd1498Szrj       target = TREE_CHAIN (target);
7038fd1498Szrj     }
7138fd1498Szrj   gcc_checking_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target)
7238fd1498Szrj 		       && ! TREE_CHAIN (target));
7338fd1498Szrj 
7438fd1498Szrj   return target;
7538fd1498Szrj }
7638fd1498Szrj 
7738fd1498Szrj 
7838fd1498Szrj /* Hash asmnames ignoring the user specified marks.  */
7938fd1498Szrj 
8038fd1498Szrj hashval_t
decl_assembler_name_hash(const_tree asmname)8138fd1498Szrj symbol_table::decl_assembler_name_hash (const_tree asmname)
8238fd1498Szrj {
8338fd1498Szrj   if (IDENTIFIER_POINTER (asmname)[0] == '*')
8438fd1498Szrj     {
8538fd1498Szrj       const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
8638fd1498Szrj       size_t ulp_len = strlen (user_label_prefix);
8738fd1498Szrj 
8838fd1498Szrj       if (ulp_len == 0)
8938fd1498Szrj 	;
9038fd1498Szrj       else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
9138fd1498Szrj 	decl_str += ulp_len;
9238fd1498Szrj 
9338fd1498Szrj       return htab_hash_string (decl_str);
9438fd1498Szrj     }
9538fd1498Szrj 
9638fd1498Szrj   return htab_hash_string (IDENTIFIER_POINTER (asmname));
9738fd1498Szrj }
9838fd1498Szrj 
9938fd1498Szrj /* Return true if assembler names NAME1 and NAME2 leads to the same symbol
10038fd1498Szrj    name.  */
10138fd1498Szrj 
10238fd1498Szrj bool
assembler_names_equal_p(const char * name1,const char * name2)10338fd1498Szrj symbol_table::assembler_names_equal_p (const char *name1, const char *name2)
10438fd1498Szrj {
10538fd1498Szrj   if (name1 != name2)
10638fd1498Szrj     {
10738fd1498Szrj       if (name1[0] == '*')
10838fd1498Szrj 	{
10938fd1498Szrj 	  size_t ulp_len = strlen (user_label_prefix);
11038fd1498Szrj 
11138fd1498Szrj 	  name1 ++;
11238fd1498Szrj 
11338fd1498Szrj 	  if (ulp_len == 0)
11438fd1498Szrj 	    ;
11538fd1498Szrj 	  else if (strncmp (name1, user_label_prefix, ulp_len) == 0)
11638fd1498Szrj 	    name1 += ulp_len;
11738fd1498Szrj 	  else
11838fd1498Szrj 	    return false;
11938fd1498Szrj 	}
12038fd1498Szrj       if (name2[0] == '*')
12138fd1498Szrj 	{
12238fd1498Szrj 	  size_t ulp_len = strlen (user_label_prefix);
12338fd1498Szrj 
12438fd1498Szrj 	  name2 ++;
12538fd1498Szrj 
12638fd1498Szrj 	  if (ulp_len == 0)
12738fd1498Szrj 	    ;
12838fd1498Szrj 	  else if (strncmp (name2, user_label_prefix, ulp_len) == 0)
12938fd1498Szrj 	    name2 += ulp_len;
13038fd1498Szrj 	  else
13138fd1498Szrj 	    return false;
13238fd1498Szrj 	}
13338fd1498Szrj       return !strcmp (name1, name2);
13438fd1498Szrj     }
13538fd1498Szrj   return true;
13638fd1498Szrj }
13738fd1498Szrj 
13838fd1498Szrj /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
13938fd1498Szrj 
14038fd1498Szrj bool
decl_assembler_name_equal(tree decl,const_tree asmname)14138fd1498Szrj symbol_table::decl_assembler_name_equal (tree decl, const_tree asmname)
14238fd1498Szrj {
14338fd1498Szrj   tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
14438fd1498Szrj   const char *decl_str;
14538fd1498Szrj   const char *asmname_str;
14638fd1498Szrj 
14738fd1498Szrj   if (decl_asmname == asmname)
14838fd1498Szrj     return true;
14938fd1498Szrj 
15038fd1498Szrj   decl_str = IDENTIFIER_POINTER (decl_asmname);
15138fd1498Szrj   asmname_str = IDENTIFIER_POINTER (asmname);
15238fd1498Szrj   return assembler_names_equal_p (decl_str, asmname_str);
15338fd1498Szrj }
15438fd1498Szrj 
15538fd1498Szrj 
15638fd1498Szrj /* Returns nonzero if P1 and P2 are equal.  */
15738fd1498Szrj 
15838fd1498Szrj /* Insert NODE to assembler name hash.  */
15938fd1498Szrj 
16038fd1498Szrj void
insert_to_assembler_name_hash(symtab_node * node,bool with_clones)16138fd1498Szrj symbol_table::insert_to_assembler_name_hash (symtab_node *node,
16238fd1498Szrj 					     bool with_clones)
16338fd1498Szrj {
16438fd1498Szrj   if (is_a <varpool_node *> (node) && DECL_HARD_REGISTER (node->decl))
16538fd1498Szrj     return;
16638fd1498Szrj   gcc_checking_assert (!node->previous_sharing_asm_name
16738fd1498Szrj 		       && !node->next_sharing_asm_name);
16838fd1498Szrj   if (assembler_name_hash)
16938fd1498Szrj     {
17038fd1498Szrj       symtab_node **aslot;
17138fd1498Szrj       cgraph_node *cnode;
17238fd1498Szrj       tree decl = node->decl;
17338fd1498Szrj 
17438fd1498Szrj       tree name = DECL_ASSEMBLER_NAME (node->decl);
17538fd1498Szrj 
17638fd1498Szrj       /* C++ FE can produce decls without associated assembler name and insert
17738fd1498Szrj 	 them to symtab to hold section or TLS information.  */
17838fd1498Szrj       if (!name)
17938fd1498Szrj 	return;
18038fd1498Szrj 
18138fd1498Szrj       hashval_t hash = decl_assembler_name_hash (name);
18238fd1498Szrj       aslot = assembler_name_hash->find_slot_with_hash (name, hash, INSERT);
18338fd1498Szrj       gcc_assert (*aslot != node);
18438fd1498Szrj       node->next_sharing_asm_name = (symtab_node *)*aslot;
18538fd1498Szrj       if (*aslot != NULL)
18638fd1498Szrj 	(*aslot)->previous_sharing_asm_name = node;
18738fd1498Szrj       *aslot = node;
18838fd1498Szrj 
18938fd1498Szrj       /* Update also possible inline clones sharing a decl.  */
19038fd1498Szrj       cnode = dyn_cast <cgraph_node *> (node);
19138fd1498Szrj       if (cnode && cnode->clones && with_clones)
19238fd1498Szrj 	for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
19338fd1498Szrj 	  if (cnode->decl == decl)
19438fd1498Szrj 	    insert_to_assembler_name_hash (cnode, true);
19538fd1498Szrj     }
19638fd1498Szrj 
19738fd1498Szrj }
19838fd1498Szrj 
19938fd1498Szrj /* Remove NODE from assembler name hash.  */
20038fd1498Szrj 
20138fd1498Szrj void
unlink_from_assembler_name_hash(symtab_node * node,bool with_clones)20238fd1498Szrj symbol_table::unlink_from_assembler_name_hash (symtab_node *node,
20338fd1498Szrj 					       bool with_clones)
20438fd1498Szrj {
20538fd1498Szrj   if (assembler_name_hash)
20638fd1498Szrj     {
20738fd1498Szrj       cgraph_node *cnode;
20838fd1498Szrj       tree decl = node->decl;
20938fd1498Szrj 
21038fd1498Szrj       if (node->next_sharing_asm_name)
21138fd1498Szrj 	node->next_sharing_asm_name->previous_sharing_asm_name
21238fd1498Szrj 	  = node->previous_sharing_asm_name;
21338fd1498Szrj       if (node->previous_sharing_asm_name)
21438fd1498Szrj 	{
21538fd1498Szrj 	  node->previous_sharing_asm_name->next_sharing_asm_name
21638fd1498Szrj 	    = node->next_sharing_asm_name;
21738fd1498Szrj 	}
21838fd1498Szrj       else
21938fd1498Szrj 	{
22038fd1498Szrj 	  tree name = DECL_ASSEMBLER_NAME (node->decl);
22138fd1498Szrj           symtab_node **slot;
22238fd1498Szrj 
22338fd1498Szrj 	  if (!name)
22438fd1498Szrj 	    return;
22538fd1498Szrj 
22638fd1498Szrj 	  hashval_t hash = decl_assembler_name_hash (name);
22738fd1498Szrj 	  slot = assembler_name_hash->find_slot_with_hash (name, hash,
22838fd1498Szrj 							   NO_INSERT);
22938fd1498Szrj 	  gcc_assert (*slot == node);
23038fd1498Szrj 	  if (!node->next_sharing_asm_name)
23138fd1498Szrj 	    assembler_name_hash->clear_slot (slot);
23238fd1498Szrj 	  else
23338fd1498Szrj 	    *slot = node->next_sharing_asm_name;
23438fd1498Szrj 	}
23538fd1498Szrj       node->next_sharing_asm_name = NULL;
23638fd1498Szrj       node->previous_sharing_asm_name = NULL;
23738fd1498Szrj 
23838fd1498Szrj       /* Update also possible inline clones sharing a decl.  */
23938fd1498Szrj       cnode = dyn_cast <cgraph_node *> (node);
24038fd1498Szrj       if (cnode && cnode->clones && with_clones)
24138fd1498Szrj 	for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
24238fd1498Szrj 	  if (cnode->decl == decl)
24338fd1498Szrj 	    unlink_from_assembler_name_hash (cnode, true);
24438fd1498Szrj     }
24538fd1498Szrj }
24638fd1498Szrj 
24738fd1498Szrj /* Arrange node to be first in its entry of assembler_name_hash.  */
24838fd1498Szrj 
24938fd1498Szrj void
symtab_prevail_in_asm_name_hash(symtab_node * node)25038fd1498Szrj symbol_table::symtab_prevail_in_asm_name_hash (symtab_node *node)
25138fd1498Szrj {
25238fd1498Szrj   unlink_from_assembler_name_hash (node, false);
25338fd1498Szrj   insert_to_assembler_name_hash (node, false);
25438fd1498Szrj }
25538fd1498Szrj 
25638fd1498Szrj /* Initalize asm name hash unless.  */
25738fd1498Szrj 
25838fd1498Szrj void
symtab_initialize_asm_name_hash(void)25938fd1498Szrj symbol_table::symtab_initialize_asm_name_hash (void)
26038fd1498Szrj {
26138fd1498Szrj   symtab_node *node;
26238fd1498Szrj   if (!assembler_name_hash)
26338fd1498Szrj     {
26438fd1498Szrj       assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
26538fd1498Szrj       FOR_EACH_SYMBOL (node)
26638fd1498Szrj 	insert_to_assembler_name_hash (node, false);
26738fd1498Szrj     }
26838fd1498Szrj }
26938fd1498Szrj 
27038fd1498Szrj /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables.  */
27138fd1498Szrj 
27238fd1498Szrj void
change_decl_assembler_name(tree decl,tree name)27338fd1498Szrj symbol_table::change_decl_assembler_name (tree decl, tree name)
27438fd1498Szrj {
27538fd1498Szrj   symtab_node *node = NULL;
27638fd1498Szrj 
27738fd1498Szrj   /* We can have user ASM names on things, like global register variables, that
27838fd1498Szrj      are not in the symbol table.  */
27938fd1498Szrj   if ((VAR_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
28038fd1498Szrj       || TREE_CODE (decl) == FUNCTION_DECL)
28138fd1498Szrj     node = symtab_node::get (decl);
28238fd1498Szrj   if (!DECL_ASSEMBLER_NAME_SET_P (decl))
28338fd1498Szrj     {
28438fd1498Szrj       SET_DECL_ASSEMBLER_NAME (decl, name);
28538fd1498Szrj       if (node)
28638fd1498Szrj 	insert_to_assembler_name_hash (node, true);
28738fd1498Szrj     }
28838fd1498Szrj   else
28938fd1498Szrj     {
29038fd1498Szrj       if (name == DECL_ASSEMBLER_NAME (decl))
29138fd1498Szrj 	return;
29238fd1498Szrj 
29338fd1498Szrj       tree alias = (IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl))
29438fd1498Szrj 		    ? TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
29538fd1498Szrj 		    : NULL);
29638fd1498Szrj       if (node)
29738fd1498Szrj 	unlink_from_assembler_name_hash (node, true);
29838fd1498Szrj 
29938fd1498Szrj       const char *old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
30038fd1498Szrj       if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
30138fd1498Szrj 	  && DECL_RTL_SET_P (decl))
30238fd1498Szrj 	warning (0, "%qD renamed after being referenced in assembly", decl);
30338fd1498Szrj 
30438fd1498Szrj       SET_DECL_ASSEMBLER_NAME (decl, name);
30538fd1498Szrj       if (alias)
30638fd1498Szrj 	{
30738fd1498Szrj 	  IDENTIFIER_TRANSPARENT_ALIAS (name) = 1;
30838fd1498Szrj 	  TREE_CHAIN (name) = alias;
30938fd1498Szrj 	}
31038fd1498Szrj       /* If we change assembler name, also all transparent aliases must
31138fd1498Szrj 	 be updated.  There are three kinds - those having same assembler name,
31238fd1498Szrj 	 those being renamed in varasm.c and weakref being renamed by the
31338fd1498Szrj 	 assembler.  */
31438fd1498Szrj       if (node)
31538fd1498Szrj 	{
31638fd1498Szrj 	  insert_to_assembler_name_hash (node, true);
31738fd1498Szrj 	  ipa_ref *ref;
31838fd1498Szrj 	  for (unsigned i = 0; node->iterate_direct_aliases (i, ref); i++)
31938fd1498Szrj 	    {
32038fd1498Szrj 	      struct symtab_node *alias = ref->referring;
32138fd1498Szrj 	      if (alias->transparent_alias && !alias->weakref
32238fd1498Szrj 		  && symbol_table::assembler_names_equal_p
32338fd1498Szrj 			 (old_name, IDENTIFIER_POINTER (
32438fd1498Szrj 				      DECL_ASSEMBLER_NAME (alias->decl))))
32538fd1498Szrj 		change_decl_assembler_name (alias->decl, name);
32638fd1498Szrj 	      else if (alias->transparent_alias
32738fd1498Szrj 		       && IDENTIFIER_TRANSPARENT_ALIAS (alias->decl))
32838fd1498Szrj 		{
32938fd1498Szrj 		  gcc_assert (TREE_CHAIN (DECL_ASSEMBLER_NAME (alias->decl))
33038fd1498Szrj 			      && IDENTIFIER_TRANSPARENT_ALIAS
33138fd1498Szrj 				     (DECL_ASSEMBLER_NAME (alias->decl)));
33238fd1498Szrj 
33338fd1498Szrj 		  TREE_CHAIN (DECL_ASSEMBLER_NAME (alias->decl)) =
33438fd1498Szrj 		    ultimate_transparent_alias_target
33538fd1498Szrj 			 (DECL_ASSEMBLER_NAME (node->decl));
33638fd1498Szrj 		}
33738fd1498Szrj #ifdef ASM_OUTPUT_WEAKREF
33838fd1498Szrj 	     else gcc_assert (!alias->transparent_alias || alias->weakref);
33938fd1498Szrj #else
34038fd1498Szrj 	     else gcc_assert (!alias->transparent_alias);
34138fd1498Szrj #endif
34238fd1498Szrj 	    }
34338fd1498Szrj 	  gcc_assert (!node->transparent_alias || !node->definition
34438fd1498Szrj 		      || node->weakref
34538fd1498Szrj 		      || TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
34638fd1498Szrj 		      || symbol_table::assembler_names_equal_p
34738fd1498Szrj 			  (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
34838fd1498Szrj 			   IDENTIFIER_POINTER
34938fd1498Szrj 			     (DECL_ASSEMBLER_NAME
35038fd1498Szrj 				 (node->get_alias_target ()->decl))));
35138fd1498Szrj 	}
35238fd1498Szrj     }
35338fd1498Szrj }
35438fd1498Szrj 
35538fd1498Szrj /* Hash sections by their names.  */
35638fd1498Szrj 
35738fd1498Szrj hashval_t
hash(section_hash_entry * n)35838fd1498Szrj section_name_hasher::hash (section_hash_entry *n)
35938fd1498Szrj {
36038fd1498Szrj   return htab_hash_string (n->name);
36138fd1498Szrj }
36238fd1498Szrj 
36338fd1498Szrj /* Return true if section P1 name equals to P2.  */
36438fd1498Szrj 
36538fd1498Szrj bool
equal(section_hash_entry * n1,const char * name)36638fd1498Szrj section_name_hasher::equal (section_hash_entry *n1, const char *name)
36738fd1498Szrj {
36838fd1498Szrj   return n1->name == name || !strcmp (n1->name, name);
36938fd1498Szrj }
37038fd1498Szrj 
37138fd1498Szrj /* Add node into symbol table.  This function is not used directly, but via
37238fd1498Szrj    cgraph/varpool node creation routines.  */
37338fd1498Szrj 
37438fd1498Szrj void
register_symbol(void)37538fd1498Szrj symtab_node::register_symbol (void)
37638fd1498Szrj {
37738fd1498Szrj   symtab->register_symbol (this);
37838fd1498Szrj 
37938fd1498Szrj   if (!decl->decl_with_vis.symtab_node)
38038fd1498Szrj     decl->decl_with_vis.symtab_node = this;
38138fd1498Szrj 
38238fd1498Szrj   ref_list.clear ();
38338fd1498Szrj 
38438fd1498Szrj   /* Be sure to do this last; C++ FE might create new nodes via
38538fd1498Szrj      DECL_ASSEMBLER_NAME langhook!  */
38638fd1498Szrj   symtab->insert_to_assembler_name_hash (this, false);
38738fd1498Szrj }
38838fd1498Szrj 
38938fd1498Szrj /* Remove NODE from same comdat group.   */
39038fd1498Szrj 
39138fd1498Szrj void
remove_from_same_comdat_group(void)39238fd1498Szrj symtab_node::remove_from_same_comdat_group (void)
39338fd1498Szrj {
39438fd1498Szrj   if (same_comdat_group)
39538fd1498Szrj     {
39638fd1498Szrj       symtab_node *prev;
39738fd1498Szrj       for (prev = same_comdat_group;
39838fd1498Szrj 	   prev->same_comdat_group != this;
39938fd1498Szrj 	   prev = prev->same_comdat_group)
40038fd1498Szrj 	;
40138fd1498Szrj       if (same_comdat_group == prev)
40238fd1498Szrj 	prev->same_comdat_group = NULL;
40338fd1498Szrj       else
40438fd1498Szrj 	prev->same_comdat_group = same_comdat_group;
40538fd1498Szrj       same_comdat_group = NULL;
40638fd1498Szrj       set_comdat_group (NULL);
40738fd1498Szrj     }
40838fd1498Szrj }
40938fd1498Szrj 
41038fd1498Szrj /* Remove node from symbol table.  This function is not used directly, but via
41138fd1498Szrj    cgraph/varpool node removal routines.  */
41238fd1498Szrj 
41338fd1498Szrj void
unregister(void)41438fd1498Szrj symtab_node::unregister (void)
41538fd1498Szrj {
41638fd1498Szrj   remove_all_references ();
41738fd1498Szrj   remove_all_referring ();
41838fd1498Szrj 
41938fd1498Szrj   /* Remove reference to section.  */
42038fd1498Szrj   set_section_for_node (NULL);
42138fd1498Szrj 
42238fd1498Szrj   remove_from_same_comdat_group ();
42338fd1498Szrj 
42438fd1498Szrj   symtab->unregister (this);
42538fd1498Szrj 
42638fd1498Szrj   /* During LTO symtab merging we temporarily corrupt decl to symtab node
42738fd1498Szrj      hash.  */
42838fd1498Szrj   gcc_assert (decl->decl_with_vis.symtab_node || in_lto_p);
42938fd1498Szrj   if (decl->decl_with_vis.symtab_node == this)
43038fd1498Szrj     {
43138fd1498Szrj       symtab_node *replacement_node = NULL;
43238fd1498Szrj       if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
43338fd1498Szrj 	replacement_node = cnode->find_replacement ();
43438fd1498Szrj       decl->decl_with_vis.symtab_node = replacement_node;
43538fd1498Szrj     }
43638fd1498Szrj   if (!is_a <varpool_node *> (this) || !DECL_HARD_REGISTER (decl))
43738fd1498Szrj     symtab->unlink_from_assembler_name_hash (this, false);
43838fd1498Szrj   if (in_init_priority_hash)
43938fd1498Szrj     symtab->init_priority_hash->remove (this);
44038fd1498Szrj }
44138fd1498Szrj 
44238fd1498Szrj 
44338fd1498Szrj /* Remove symbol from symbol table.  */
44438fd1498Szrj 
44538fd1498Szrj void
remove(void)44638fd1498Szrj symtab_node::remove (void)
44738fd1498Szrj {
44838fd1498Szrj   if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
44938fd1498Szrj     cnode->remove ();
45038fd1498Szrj   else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
45138fd1498Szrj     vnode->remove ();
45238fd1498Szrj }
45338fd1498Szrj 
45438fd1498Szrj /* Add NEW_ to the same comdat group that OLD is in.  */
45538fd1498Szrj 
45638fd1498Szrj void
add_to_same_comdat_group(symtab_node * old_node)45738fd1498Szrj symtab_node::add_to_same_comdat_group (symtab_node *old_node)
45838fd1498Szrj {
45938fd1498Szrj   gcc_assert (old_node->get_comdat_group ());
46038fd1498Szrj   gcc_assert (!same_comdat_group);
46138fd1498Szrj   gcc_assert (this != old_node);
46238fd1498Szrj 
46338fd1498Szrj   set_comdat_group (old_node->get_comdat_group ());
46438fd1498Szrj   same_comdat_group = old_node;
46538fd1498Szrj   if (!old_node->same_comdat_group)
46638fd1498Szrj     old_node->same_comdat_group = this;
46738fd1498Szrj   else
46838fd1498Szrj     {
46938fd1498Szrj       symtab_node *n;
47038fd1498Szrj       for (n = old_node->same_comdat_group;
47138fd1498Szrj 	   n->same_comdat_group != old_node;
47238fd1498Szrj 	   n = n->same_comdat_group)
47338fd1498Szrj 	;
47438fd1498Szrj       n->same_comdat_group = this;
47538fd1498Szrj     }
47638fd1498Szrj }
47738fd1498Szrj 
47838fd1498Szrj /* Dissolve the same_comdat_group list in which NODE resides.  */
47938fd1498Szrj 
48038fd1498Szrj void
dissolve_same_comdat_group_list(void)48138fd1498Szrj symtab_node::dissolve_same_comdat_group_list (void)
48238fd1498Szrj {
48338fd1498Szrj   symtab_node *n = this;
48438fd1498Szrj   symtab_node *next;
48538fd1498Szrj 
48638fd1498Szrj   if (!same_comdat_group)
48738fd1498Szrj     return;
48838fd1498Szrj   do
48938fd1498Szrj     {
49038fd1498Szrj       next = n->same_comdat_group;
49138fd1498Szrj       n->same_comdat_group = NULL;
49238fd1498Szrj       /* Clear comdat_group for comdat locals, since
49338fd1498Szrj          make_decl_local doesn't.  */
49438fd1498Szrj       if (!TREE_PUBLIC (n->decl))
49538fd1498Szrj 	n->set_comdat_group (NULL);
49638fd1498Szrj       n = next;
49738fd1498Szrj     }
49838fd1498Szrj   while (n != this);
49938fd1498Szrj }
50038fd1498Szrj 
50138fd1498Szrj /* Return printable assembler name of NODE.
50238fd1498Szrj    This function is used only for debugging.  When assembler name
50338fd1498Szrj    is unknown go with identifier name.  */
50438fd1498Szrj 
50538fd1498Szrj const char *
asm_name()50638fd1498Szrj symtab_node::asm_name () const
50738fd1498Szrj {
50838fd1498Szrj   if (!DECL_ASSEMBLER_NAME_SET_P (decl))
50938fd1498Szrj     return name ();
51038fd1498Szrj   return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
51138fd1498Szrj }
51238fd1498Szrj 
51338fd1498Szrj /* Return printable identifier name.  */
51438fd1498Szrj 
51538fd1498Szrj const char *
name()51638fd1498Szrj symtab_node::name () const
51738fd1498Szrj {
51838fd1498Szrj   if (!DECL_NAME (decl))
51938fd1498Szrj     {
52038fd1498Szrj       if (DECL_ASSEMBLER_NAME_SET_P (decl))
52138fd1498Szrj 	return asm_name ();
52238fd1498Szrj       else
52338fd1498Szrj         return "<unnamed>";
52438fd1498Szrj     }
52538fd1498Szrj   return lang_hooks.decl_printable_name (decl, 2);
52638fd1498Szrj }
52738fd1498Szrj 
52838fd1498Szrj const char *
get_dump_name(bool asm_name_p)52938fd1498Szrj symtab_node::get_dump_name (bool asm_name_p) const
53038fd1498Szrj {
53138fd1498Szrj #define EXTRA 16
53238fd1498Szrj   const char *fname = asm_name_p ? asm_name () : name ();
53338fd1498Szrj   unsigned l = strlen (fname);
53438fd1498Szrj 
53538fd1498Szrj   char *s = (char *)ggc_internal_cleared_alloc (l + EXTRA);
53638fd1498Szrj   snprintf (s, l + EXTRA, "%s/%d", fname, order);
53738fd1498Szrj 
53838fd1498Szrj   return s;
53938fd1498Szrj }
54038fd1498Szrj 
54138fd1498Szrj const char *
dump_name()54238fd1498Szrj symtab_node::dump_name () const
54338fd1498Szrj {
54438fd1498Szrj   return get_dump_name (false);
54538fd1498Szrj }
54638fd1498Szrj 
54738fd1498Szrj const char *
dump_asm_name()54838fd1498Szrj symtab_node::dump_asm_name () const
54938fd1498Szrj {
55038fd1498Szrj   return get_dump_name (true);
55138fd1498Szrj }
55238fd1498Szrj 
55338fd1498Szrj /* Return ipa reference from this symtab_node to
55438fd1498Szrj    REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
55538fd1498Szrj    of the use.  */
55638fd1498Szrj 
55738fd1498Szrj ipa_ref *
create_reference(symtab_node * referred_node,enum ipa_ref_use use_type)55838fd1498Szrj symtab_node::create_reference (symtab_node *referred_node,
55938fd1498Szrj 			       enum ipa_ref_use use_type)
56038fd1498Szrj {
56138fd1498Szrj   return create_reference (referred_node, use_type, NULL);
56238fd1498Szrj }
56338fd1498Szrj 
56438fd1498Szrj 
56538fd1498Szrj /* Return ipa reference from this symtab_node to
56638fd1498Szrj    REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
56738fd1498Szrj    of the use and STMT the statement (if it exists).  */
56838fd1498Szrj 
56938fd1498Szrj ipa_ref *
create_reference(symtab_node * referred_node,enum ipa_ref_use use_type,gimple * stmt)57038fd1498Szrj symtab_node::create_reference (symtab_node *referred_node,
57138fd1498Szrj 			       enum ipa_ref_use use_type, gimple *stmt)
57238fd1498Szrj {
57338fd1498Szrj   ipa_ref *ref = NULL, *ref2 = NULL;
57438fd1498Szrj   ipa_ref_list *list, *list2;
57538fd1498Szrj   ipa_ref_t *old_references;
57638fd1498Szrj 
57738fd1498Szrj   gcc_checking_assert (!stmt || is_a <cgraph_node *> (this));
57838fd1498Szrj   gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);
57938fd1498Szrj 
58038fd1498Szrj   list = &ref_list;
58138fd1498Szrj   old_references = vec_safe_address (list->references);
58238fd1498Szrj   vec_safe_grow (list->references, vec_safe_length (list->references) + 1);
58338fd1498Szrj   ref = &list->references->last ();
58438fd1498Szrj 
58538fd1498Szrj   list2 = &referred_node->ref_list;
58638fd1498Szrj 
58738fd1498Szrj   /* IPA_REF_ALIAS is always inserted at the beginning of the list.   */
58838fd1498Szrj   if(use_type == IPA_REF_ALIAS)
58938fd1498Szrj     {
59038fd1498Szrj       list2->referring.safe_insert (0, ref);
59138fd1498Szrj       ref->referred_index = 0;
59238fd1498Szrj 
59338fd1498Szrj       for (unsigned int i = 1; i < list2->referring.length (); i++)
59438fd1498Szrj 	list2->referring[i]->referred_index = i;
59538fd1498Szrj     }
59638fd1498Szrj   else
59738fd1498Szrj     {
59838fd1498Szrj       list2->referring.safe_push (ref);
59938fd1498Szrj       ref->referred_index = list2->referring.length () - 1;
60038fd1498Szrj     }
60138fd1498Szrj 
60238fd1498Szrj   ref->referring = this;
60338fd1498Szrj   ref->referred = referred_node;
60438fd1498Szrj   ref->stmt = stmt;
60538fd1498Szrj   ref->lto_stmt_uid = 0;
60638fd1498Szrj   ref->use = use_type;
60738fd1498Szrj   ref->speculative = 0;
60838fd1498Szrj 
60938fd1498Szrj   /* If vector was moved in memory, update pointers.  */
61038fd1498Szrj   if (old_references != list->references->address ())
61138fd1498Szrj     {
61238fd1498Szrj       int i;
61338fd1498Szrj       for (i = 0; iterate_reference(i, ref2); i++)
61438fd1498Szrj 	ref2->referred_ref_list ()->referring[ref2->referred_index] = ref2;
61538fd1498Szrj     }
61638fd1498Szrj   return ref;
61738fd1498Szrj }
61838fd1498Szrj 
61938fd1498Szrj ipa_ref *
maybe_create_reference(tree val,gimple * stmt)62038fd1498Szrj symtab_node::maybe_create_reference (tree val, gimple *stmt)
62138fd1498Szrj {
62238fd1498Szrj   STRIP_NOPS (val);
62338fd1498Szrj   ipa_ref_use use_type;
62438fd1498Szrj 
62538fd1498Szrj   switch (TREE_CODE (val))
62638fd1498Szrj     {
62738fd1498Szrj     case VAR_DECL:
62838fd1498Szrj       use_type = IPA_REF_LOAD;
62938fd1498Szrj       break;
63038fd1498Szrj     case ADDR_EXPR:
63138fd1498Szrj       use_type = IPA_REF_ADDR;
63238fd1498Szrj       break;
63338fd1498Szrj     default:
63438fd1498Szrj       gcc_assert (!handled_component_p (val));
63538fd1498Szrj       return NULL;
63638fd1498Szrj     }
63738fd1498Szrj 
63838fd1498Szrj   val = get_base_var (val);
63938fd1498Szrj   if (val && VAR_OR_FUNCTION_DECL_P (val))
64038fd1498Szrj     {
64138fd1498Szrj       symtab_node *referred = symtab_node::get (val);
64238fd1498Szrj       gcc_checking_assert (referred);
64338fd1498Szrj       return create_reference (referred, use_type, stmt);
64438fd1498Szrj     }
64538fd1498Szrj   return NULL;
64638fd1498Szrj }
64738fd1498Szrj 
64838fd1498Szrj /* Clone all references from symtab NODE to this symtab_node.  */
64938fd1498Szrj 
65038fd1498Szrj void
clone_references(symtab_node * node)65138fd1498Szrj symtab_node::clone_references (symtab_node *node)
65238fd1498Szrj {
65338fd1498Szrj   ipa_ref *ref = NULL, *ref2 = NULL;
65438fd1498Szrj   int i;
65538fd1498Szrj   for (i = 0; node->iterate_reference (i, ref); i++)
65638fd1498Szrj     {
65738fd1498Szrj       bool speculative = ref->speculative;
65838fd1498Szrj       unsigned int stmt_uid = ref->lto_stmt_uid;
65938fd1498Szrj 
66038fd1498Szrj       ref2 = create_reference (ref->referred, ref->use, ref->stmt);
66138fd1498Szrj       ref2->speculative = speculative;
66238fd1498Szrj       ref2->lto_stmt_uid = stmt_uid;
66338fd1498Szrj     }
66438fd1498Szrj }
66538fd1498Szrj 
66638fd1498Szrj /* Clone all referring from symtab NODE to this symtab_node.  */
66738fd1498Szrj 
66838fd1498Szrj void
clone_referring(symtab_node * node)66938fd1498Szrj symtab_node::clone_referring (symtab_node *node)
67038fd1498Szrj {
67138fd1498Szrj   ipa_ref *ref = NULL, *ref2 = NULL;
67238fd1498Szrj   int i;
67338fd1498Szrj   for (i = 0; node->iterate_referring(i, ref); i++)
67438fd1498Szrj     {
67538fd1498Szrj       bool speculative = ref->speculative;
67638fd1498Szrj       unsigned int stmt_uid = ref->lto_stmt_uid;
67738fd1498Szrj 
67838fd1498Szrj       ref2 = ref->referring->create_reference (this, ref->use, ref->stmt);
67938fd1498Szrj       ref2->speculative = speculative;
68038fd1498Szrj       ref2->lto_stmt_uid = stmt_uid;
68138fd1498Szrj     }
68238fd1498Szrj }
68338fd1498Szrj 
68438fd1498Szrj /* Clone reference REF to this symtab_node and set its stmt to STMT.  */
68538fd1498Szrj 
68638fd1498Szrj ipa_ref *
clone_reference(ipa_ref * ref,gimple * stmt)68738fd1498Szrj symtab_node::clone_reference (ipa_ref *ref, gimple *stmt)
68838fd1498Szrj {
68938fd1498Szrj   bool speculative = ref->speculative;
69038fd1498Szrj   unsigned int stmt_uid = ref->lto_stmt_uid;
69138fd1498Szrj   ipa_ref *ref2;
69238fd1498Szrj 
69338fd1498Szrj   ref2 = create_reference (ref->referred, ref->use, stmt);
69438fd1498Szrj   ref2->speculative = speculative;
69538fd1498Szrj   ref2->lto_stmt_uid = stmt_uid;
69638fd1498Szrj   return ref2;
69738fd1498Szrj }
69838fd1498Szrj 
69938fd1498Szrj /* Find the structure describing a reference to REFERRED_NODE
70038fd1498Szrj    and associated with statement STMT.  */
70138fd1498Szrj 
70238fd1498Szrj ipa_ref *
find_reference(symtab_node * referred_node,gimple * stmt,unsigned int lto_stmt_uid)70338fd1498Szrj symtab_node::find_reference (symtab_node *referred_node,
70438fd1498Szrj 			     gimple *stmt, unsigned int lto_stmt_uid)
70538fd1498Szrj {
70638fd1498Szrj   ipa_ref *r = NULL;
70738fd1498Szrj   int i;
70838fd1498Szrj 
70938fd1498Szrj   for (i = 0; iterate_reference (i, r); i++)
71038fd1498Szrj     if (r->referred == referred_node
71138fd1498Szrj 	&& !r->speculative
71238fd1498Szrj 	&& ((stmt && r->stmt == stmt)
71338fd1498Szrj 	    || (lto_stmt_uid && r->lto_stmt_uid == lto_stmt_uid)
71438fd1498Szrj 	    || (!stmt && !lto_stmt_uid && !r->stmt && !r->lto_stmt_uid)))
71538fd1498Szrj       return r;
71638fd1498Szrj   return NULL;
71738fd1498Szrj }
71838fd1498Szrj 
71938fd1498Szrj /* Remove all references that are associated with statement STMT.  */
72038fd1498Szrj 
72138fd1498Szrj void
remove_stmt_references(gimple * stmt)72238fd1498Szrj symtab_node::remove_stmt_references (gimple *stmt)
72338fd1498Szrj {
72438fd1498Szrj   ipa_ref *r = NULL;
72538fd1498Szrj   int i = 0;
72638fd1498Szrj 
72738fd1498Szrj   while (iterate_reference (i, r))
72838fd1498Szrj     if (r->stmt == stmt)
72938fd1498Szrj       r->remove_reference ();
73038fd1498Szrj     else
73138fd1498Szrj       i++;
73238fd1498Szrj }
73338fd1498Szrj 
73438fd1498Szrj /* Remove all stmt references in non-speculative references.
73538fd1498Szrj    Those are not maintained during inlining & clonning.
73638fd1498Szrj    The exception are speculative references that are updated along
73738fd1498Szrj    with callgraph edges associated with them.  */
73838fd1498Szrj 
73938fd1498Szrj void
clear_stmts_in_references(void)74038fd1498Szrj symtab_node::clear_stmts_in_references (void)
74138fd1498Szrj {
74238fd1498Szrj   ipa_ref *r = NULL;
74338fd1498Szrj   int i;
74438fd1498Szrj 
74538fd1498Szrj   for (i = 0; iterate_reference (i, r); i++)
74638fd1498Szrj     if (!r->speculative)
74738fd1498Szrj       {
74838fd1498Szrj 	r->stmt = NULL;
74938fd1498Szrj 	r->lto_stmt_uid = 0;
75038fd1498Szrj       }
75138fd1498Szrj }
75238fd1498Szrj 
75338fd1498Szrj /* Remove all references in ref list.  */
75438fd1498Szrj 
75538fd1498Szrj void
remove_all_references(void)75638fd1498Szrj symtab_node::remove_all_references (void)
75738fd1498Szrj {
75838fd1498Szrj   while (vec_safe_length (ref_list.references))
75938fd1498Szrj     ref_list.references->last ().remove_reference ();
76038fd1498Szrj   vec_free (ref_list.references);
76138fd1498Szrj }
76238fd1498Szrj 
76338fd1498Szrj /* Remove all referring items in ref list.  */
76438fd1498Szrj 
76538fd1498Szrj void
remove_all_referring(void)76638fd1498Szrj symtab_node::remove_all_referring (void)
76738fd1498Szrj {
76838fd1498Szrj   while (ref_list.referring.length ())
76938fd1498Szrj     ref_list.referring.last ()->remove_reference ();
77038fd1498Szrj   ref_list.referring.release ();
77138fd1498Szrj }
77238fd1498Szrj 
77338fd1498Szrj /* Dump references in ref list to FILE.  */
77438fd1498Szrj 
77538fd1498Szrj void
dump_references(FILE * file)77638fd1498Szrj symtab_node::dump_references (FILE *file)
77738fd1498Szrj {
77838fd1498Szrj   ipa_ref *ref = NULL;
77938fd1498Szrj   int i;
78038fd1498Szrj   for (i = 0; iterate_reference (i, ref); i++)
78138fd1498Szrj     {
78238fd1498Szrj       fprintf (file, "%s (%s)",
78338fd1498Szrj 	       ref->referred->dump_asm_name (),
78438fd1498Szrj 	       ipa_ref_use_name [ref->use]);
78538fd1498Szrj       if (ref->speculative)
78638fd1498Szrj 	fprintf (file, " (speculative)");
78738fd1498Szrj     }
78838fd1498Szrj   fprintf (file, "\n");
78938fd1498Szrj }
79038fd1498Szrj 
79138fd1498Szrj /* Dump referring in list to FILE.  */
79238fd1498Szrj 
79338fd1498Szrj void
dump_referring(FILE * file)79438fd1498Szrj symtab_node::dump_referring (FILE *file)
79538fd1498Szrj {
79638fd1498Szrj   ipa_ref *ref = NULL;
79738fd1498Szrj   int i;
79838fd1498Szrj   for (i = 0; iterate_referring(i, ref); i++)
79938fd1498Szrj     {
80038fd1498Szrj       fprintf (file, "%s (%s)",
80138fd1498Szrj 	       ref->referring->dump_asm_name (),
80238fd1498Szrj 	       ipa_ref_use_name [ref->use]);
80338fd1498Szrj       if (ref->speculative)
80438fd1498Szrj 	fprintf (file, " (speculative)");
80538fd1498Szrj     }
80638fd1498Szrj   fprintf (file, "\n");
80738fd1498Szrj }
80838fd1498Szrj 
80938fd1498Szrj static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
81038fd1498Szrj 
81138fd1498Szrj /* Dump base fields of symtab nodes to F.  Not to be used directly.  */
81238fd1498Szrj 
81338fd1498Szrj void
dump_base(FILE * f)81438fd1498Szrj symtab_node::dump_base (FILE *f)
81538fd1498Szrj {
81638fd1498Szrj   static const char * const visibility_types[] = {
81738fd1498Szrj     "default", "protected", "hidden", "internal"
81838fd1498Szrj   };
81938fd1498Szrj 
82038fd1498Szrj   fprintf (f, "%s (%s)", dump_asm_name (), name ());
82138fd1498Szrj   dump_addr (f, " @", (void *)this);
82238fd1498Szrj   fprintf (f, "\n  Type: %s", symtab_type_names[type]);
82338fd1498Szrj 
82438fd1498Szrj   if (definition)
82538fd1498Szrj     fprintf (f, " definition");
82638fd1498Szrj   if (analyzed)
82738fd1498Szrj     fprintf (f, " analyzed");
82838fd1498Szrj   if (alias)
82938fd1498Szrj     fprintf (f, " alias");
83038fd1498Szrj   if (transparent_alias)
83138fd1498Szrj     fprintf (f, " transparent_alias");
83238fd1498Szrj   if (weakref)
83338fd1498Szrj     fprintf (f, " weakref");
83438fd1498Szrj   if (cpp_implicit_alias)
83538fd1498Szrj     fprintf (f, " cpp_implicit_alias");
83638fd1498Szrj   if (alias_target)
83738fd1498Szrj     fprintf (f, " target:%s",
83838fd1498Szrj 	     DECL_P (alias_target)
83938fd1498Szrj 	     ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
84038fd1498Szrj 				     (alias_target))
84138fd1498Szrj 	     : IDENTIFIER_POINTER (alias_target));
84238fd1498Szrj   if (body_removed)
84338fd1498Szrj     fprintf (f, "\n  Body removed by symtab_remove_unreachable_nodes");
84438fd1498Szrj   fprintf (f, "\n  Visibility:");
84538fd1498Szrj   if (in_other_partition)
84638fd1498Szrj     fprintf (f, " in_other_partition");
84738fd1498Szrj   if (used_from_other_partition)
84838fd1498Szrj     fprintf (f, " used_from_other_partition");
84938fd1498Szrj   if (force_output)
85038fd1498Szrj     fprintf (f, " force_output");
85138fd1498Szrj   if (forced_by_abi)
85238fd1498Szrj     fprintf (f, " forced_by_abi");
85338fd1498Szrj   if (externally_visible)
85438fd1498Szrj     fprintf (f, " externally_visible");
85538fd1498Szrj   if (no_reorder)
85638fd1498Szrj     fprintf (f, " no_reorder");
85738fd1498Szrj   if (resolution != LDPR_UNKNOWN)
85838fd1498Szrj     fprintf (f, " %s",
85938fd1498Szrj  	     ld_plugin_symbol_resolution_names[(int)resolution]);
86038fd1498Szrj   if (TREE_ASM_WRITTEN (decl))
86138fd1498Szrj     fprintf (f, " asm_written");
86238fd1498Szrj   if (DECL_EXTERNAL (decl))
86338fd1498Szrj     fprintf (f, " external");
86438fd1498Szrj   if (TREE_PUBLIC (decl))
86538fd1498Szrj     fprintf (f, " public");
86638fd1498Szrj   if (DECL_COMMON (decl))
86738fd1498Szrj     fprintf (f, " common");
86838fd1498Szrj   if (DECL_WEAK (decl))
86938fd1498Szrj     fprintf (f, " weak");
87038fd1498Szrj   if (DECL_DLLIMPORT_P (decl))
87138fd1498Szrj     fprintf (f, " dll_import");
87238fd1498Szrj   if (DECL_COMDAT (decl))
87338fd1498Szrj     fprintf (f, " comdat");
87438fd1498Szrj   if (get_comdat_group ())
87538fd1498Szrj     fprintf (f, " comdat_group:%s",
87638fd1498Szrj 	     IDENTIFIER_POINTER (get_comdat_group_id ()));
87738fd1498Szrj   if (DECL_ONE_ONLY (decl))
87838fd1498Szrj     fprintf (f, " one_only");
87938fd1498Szrj   if (get_section ())
88038fd1498Szrj     fprintf (f, " section:%s",
88138fd1498Szrj 	     get_section ());
88238fd1498Szrj   if (implicit_section)
88338fd1498Szrj     fprintf (f," (implicit_section)");
88438fd1498Szrj   if (DECL_VISIBILITY_SPECIFIED (decl))
88538fd1498Szrj     fprintf (f, " visibility_specified");
88638fd1498Szrj   if (DECL_VISIBILITY (decl))
88738fd1498Szrj     fprintf (f, " visibility:%s",
88838fd1498Szrj 	     visibility_types [DECL_VISIBILITY (decl)]);
88938fd1498Szrj   if (DECL_VIRTUAL_P (decl))
89038fd1498Szrj     fprintf (f, " virtual");
89138fd1498Szrj   if (DECL_ARTIFICIAL (decl))
89238fd1498Szrj     fprintf (f, " artificial");
89338fd1498Szrj   if (TREE_CODE (decl) == FUNCTION_DECL)
89438fd1498Szrj     {
89538fd1498Szrj       if (DECL_STATIC_CONSTRUCTOR (decl))
89638fd1498Szrj 	fprintf (f, " constructor");
89738fd1498Szrj       if (DECL_STATIC_DESTRUCTOR (decl))
89838fd1498Szrj 	fprintf (f, " destructor");
89938fd1498Szrj     }
90038fd1498Szrj   fprintf (f, "\n");
90138fd1498Szrj 
90238fd1498Szrj   if (same_comdat_group)
90338fd1498Szrj     fprintf (f, "  Same comdat group as: %s\n",
90438fd1498Szrj 	     same_comdat_group->dump_asm_name ());
90538fd1498Szrj   if (next_sharing_asm_name)
90638fd1498Szrj     fprintf (f, "  next sharing asm name: %i\n",
90738fd1498Szrj 	     next_sharing_asm_name->order);
90838fd1498Szrj   if (previous_sharing_asm_name)
90938fd1498Szrj     fprintf (f, "  previous sharing asm name: %i\n",
91038fd1498Szrj 	     previous_sharing_asm_name->order);
91138fd1498Szrj 
91238fd1498Szrj   if (address_taken)
91338fd1498Szrj     fprintf (f, "  Address is taken.\n");
91438fd1498Szrj   if (aux)
91538fd1498Szrj     {
91638fd1498Szrj       fprintf (f, "  Aux:");
91738fd1498Szrj       dump_addr (f, " @", (void *)aux);
91838fd1498Szrj       fprintf (f, "\n");
91938fd1498Szrj     }
92038fd1498Szrj 
92138fd1498Szrj   fprintf (f, "  References: ");
92238fd1498Szrj   dump_references (f);
92338fd1498Szrj   fprintf (f, "  Referring: ");
92438fd1498Szrj   dump_referring (f);
92538fd1498Szrj   if (lto_file_data)
92638fd1498Szrj     fprintf (f, "  Read from file: %s\n",
92738fd1498Szrj 	     lto_file_data->file_name);
92838fd1498Szrj }
92938fd1498Szrj 
93038fd1498Szrj /* Dump symtab node to F.  */
93138fd1498Szrj 
93238fd1498Szrj void
dump(FILE * f)93338fd1498Szrj symtab_node::dump (FILE *f)
93438fd1498Szrj {
93538fd1498Szrj   if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
93638fd1498Szrj     cnode->dump (f);
93738fd1498Szrj   else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
93838fd1498Szrj     vnode->dump (f);
93938fd1498Szrj }
94038fd1498Szrj 
94138fd1498Szrj void
dump(FILE * f)94238fd1498Szrj symbol_table::dump (FILE *f)
94338fd1498Szrj {
94438fd1498Szrj   symtab_node *node;
94538fd1498Szrj   fprintf (f, "Symbol table:\n\n");
94638fd1498Szrj   FOR_EACH_SYMBOL (node)
94738fd1498Szrj     node->dump (f);
94838fd1498Szrj }
94938fd1498Szrj 
95038fd1498Szrj DEBUG_FUNCTION void
debug(void)95138fd1498Szrj symbol_table::debug (void)
95238fd1498Szrj {
95338fd1498Szrj   dump (stderr);
95438fd1498Szrj }
95538fd1498Szrj 
95638fd1498Szrj /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
95738fd1498Szrj    Return NULL if there's no such node.  */
95838fd1498Szrj 
95938fd1498Szrj symtab_node *
get_for_asmname(const_tree asmname)96038fd1498Szrj symtab_node::get_for_asmname (const_tree asmname)
96138fd1498Szrj {
96238fd1498Szrj   symtab_node *node;
96338fd1498Szrj 
96438fd1498Szrj   symtab->symtab_initialize_asm_name_hash ();
96538fd1498Szrj   hashval_t hash = symtab->decl_assembler_name_hash (asmname);
96638fd1498Szrj   symtab_node **slot
96738fd1498Szrj     = symtab->assembler_name_hash->find_slot_with_hash (asmname, hash,
96838fd1498Szrj 							NO_INSERT);
96938fd1498Szrj 
97038fd1498Szrj   if (slot)
97138fd1498Szrj     {
97238fd1498Szrj       node = *slot;
97338fd1498Szrj       return node;
97438fd1498Szrj     }
97538fd1498Szrj   return NULL;
97638fd1498Szrj }
97738fd1498Szrj 
97838fd1498Szrj /* Dump symtab node NODE to stderr.  */
97938fd1498Szrj 
98038fd1498Szrj DEBUG_FUNCTION void
debug(void)98138fd1498Szrj symtab_node::debug (void)
98238fd1498Szrj {
98338fd1498Szrj   dump (stderr);
98438fd1498Szrj }
98538fd1498Szrj 
98638fd1498Szrj /* Verify common part of symtab nodes.  */
98738fd1498Szrj 
98838fd1498Szrj DEBUG_FUNCTION bool
verify_base(void)98938fd1498Szrj symtab_node::verify_base (void)
99038fd1498Szrj {
99138fd1498Szrj   bool error_found = false;
99238fd1498Szrj   symtab_node *hashed_node;
99338fd1498Szrj 
99438fd1498Szrj   if (is_a <cgraph_node *> (this))
99538fd1498Szrj     {
99638fd1498Szrj       if (TREE_CODE (decl) != FUNCTION_DECL)
99738fd1498Szrj 	{
99838fd1498Szrj           error ("function symbol is not function");
99938fd1498Szrj           error_found = true;
100038fd1498Szrj 	}
1001*58e805e6Szrj       else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
1002*58e805e6Szrj 		!= NULL)
1003*58e805e6Szrj 	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
1004*58e805e6Szrj 	{
1005*58e805e6Szrj           error ("inconsistent `ifunc' attribute");
1006*58e805e6Szrj           error_found = true;
1007*58e805e6Szrj 	}
100838fd1498Szrj     }
100938fd1498Szrj   else if (is_a <varpool_node *> (this))
101038fd1498Szrj     {
101138fd1498Szrj       if (!VAR_P (decl))
101238fd1498Szrj 	{
101338fd1498Szrj           error ("variable symbol is not variable");
101438fd1498Szrj           error_found = true;
101538fd1498Szrj 	}
101638fd1498Szrj     }
101738fd1498Szrj   else
101838fd1498Szrj     {
101938fd1498Szrj       error ("node has unknown type");
102038fd1498Szrj       error_found = true;
102138fd1498Szrj     }
102238fd1498Szrj 
102338fd1498Szrj   if (symtab->state != LTO_STREAMING)
102438fd1498Szrj     {
102538fd1498Szrj       hashed_node = symtab_node::get (decl);
102638fd1498Szrj       if (!hashed_node)
102738fd1498Szrj 	{
102838fd1498Szrj 	  error ("node not found node->decl->decl_with_vis.symtab_node");
102938fd1498Szrj 	  error_found = true;
103038fd1498Szrj 	}
103138fd1498Szrj       if (hashed_node != this
103238fd1498Szrj 	  && (!is_a <cgraph_node *> (this)
103338fd1498Szrj 	      || !dyn_cast <cgraph_node *> (this)->clone_of
103438fd1498Szrj 	      || dyn_cast <cgraph_node *> (this)->clone_of->decl != decl))
103538fd1498Szrj 	{
103638fd1498Szrj 	  error ("node differs from node->decl->decl_with_vis.symtab_node");
103738fd1498Szrj 	  error_found = true;
103838fd1498Szrj 	}
103938fd1498Szrj     }
104038fd1498Szrj   if (symtab->assembler_name_hash)
104138fd1498Szrj     {
104238fd1498Szrj       hashed_node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (decl));
104338fd1498Szrj       if (hashed_node && hashed_node->previous_sharing_asm_name)
104438fd1498Szrj 	{
104538fd1498Szrj           error ("assembler name hash list corrupted");
104638fd1498Szrj           error_found = true;
104738fd1498Szrj 	}
104838fd1498Szrj       while (hashed_node)
104938fd1498Szrj 	{
105038fd1498Szrj 	  if (hashed_node == this)
105138fd1498Szrj 	    break;
105238fd1498Szrj 	  hashed_node = hashed_node->next_sharing_asm_name;
105338fd1498Szrj 	}
105438fd1498Szrj       if (!hashed_node
105538fd1498Szrj 	  && !(is_a <varpool_node *> (this)
105638fd1498Szrj 	       && DECL_HARD_REGISTER (decl)))
105738fd1498Szrj 	{
105838fd1498Szrj           error ("node not found in symtab assembler name hash");
105938fd1498Szrj           error_found = true;
106038fd1498Szrj 	}
106138fd1498Szrj     }
106238fd1498Szrj   if (previous_sharing_asm_name
106338fd1498Szrj       && previous_sharing_asm_name->next_sharing_asm_name != this)
106438fd1498Szrj     {
106538fd1498Szrj       error ("double linked list of assembler names corrupted");
106638fd1498Szrj       error_found = true;
106738fd1498Szrj     }
106838fd1498Szrj   if (body_removed && definition)
106938fd1498Szrj     {
107038fd1498Szrj       error ("node has body_removed but is definition");
107138fd1498Szrj       error_found = true;
107238fd1498Szrj     }
107338fd1498Szrj   if (analyzed && !definition)
107438fd1498Szrj     {
107538fd1498Szrj       error ("node is analyzed but it is not a definition");
107638fd1498Szrj       error_found = true;
107738fd1498Szrj     }
107838fd1498Szrj   if (cpp_implicit_alias && !alias)
107938fd1498Szrj     {
108038fd1498Szrj       error ("node is alias but not implicit alias");
108138fd1498Szrj       error_found = true;
108238fd1498Szrj     }
108338fd1498Szrj   if (alias && !definition && !weakref)
108438fd1498Szrj     {
108538fd1498Szrj       error ("node is alias but not definition");
108638fd1498Szrj       error_found = true;
108738fd1498Szrj     }
108838fd1498Szrj   if (weakref && !transparent_alias)
108938fd1498Szrj     {
109038fd1498Szrj       error ("node is weakref but not an transparent_alias");
109138fd1498Szrj       error_found = true;
109238fd1498Szrj     }
109338fd1498Szrj   if (transparent_alias && !alias)
109438fd1498Szrj     {
109538fd1498Szrj       error ("node is transparent_alias but not an alias");
109638fd1498Szrj       error_found = true;
109738fd1498Szrj     }
109838fd1498Szrj   if (same_comdat_group)
109938fd1498Szrj     {
110038fd1498Szrj       symtab_node *n = same_comdat_group;
110138fd1498Szrj 
110238fd1498Szrj       if (!n->get_comdat_group ())
110338fd1498Szrj 	{
110438fd1498Szrj 	  error ("node is in same_comdat_group list but has no comdat_group");
110538fd1498Szrj 	  error_found = true;
110638fd1498Szrj 	}
110738fd1498Szrj       if (n->get_comdat_group () != get_comdat_group ())
110838fd1498Szrj 	{
110938fd1498Szrj 	  error ("same_comdat_group list across different groups");
111038fd1498Szrj 	  error_found = true;
111138fd1498Szrj 	}
111238fd1498Szrj       if (n->type != type)
111338fd1498Szrj 	{
111438fd1498Szrj 	  error ("mixing different types of symbol in same comdat groups is not supported");
111538fd1498Szrj 	  error_found = true;
111638fd1498Szrj 	}
111738fd1498Szrj       if (n == this)
111838fd1498Szrj 	{
111938fd1498Szrj 	  error ("node is alone in a comdat group");
112038fd1498Szrj 	  error_found = true;
112138fd1498Szrj 	}
112238fd1498Szrj       do
112338fd1498Szrj 	{
112438fd1498Szrj 	  if (!n->same_comdat_group)
112538fd1498Szrj 	    {
112638fd1498Szrj 	      error ("same_comdat_group is not a circular list");
112738fd1498Szrj 	      error_found = true;
112838fd1498Szrj 	      break;
112938fd1498Szrj 	    }
113038fd1498Szrj 	  n = n->same_comdat_group;
113138fd1498Szrj 	}
113238fd1498Szrj       while (n != this);
113338fd1498Szrj       if (comdat_local_p ())
113438fd1498Szrj 	{
113538fd1498Szrj 	  ipa_ref *ref = NULL;
113638fd1498Szrj 
113738fd1498Szrj 	  for (int i = 0; iterate_referring (i, ref); ++i)
113838fd1498Szrj 	    {
113938fd1498Szrj 	      if (!in_same_comdat_group_p (ref->referring))
114038fd1498Szrj 		{
114138fd1498Szrj 		  error ("comdat-local symbol referred to by %s outside its "
114238fd1498Szrj 			 "comdat",
114338fd1498Szrj 			 identifier_to_locale (ref->referring->name()));
114438fd1498Szrj 		  error_found = true;
114538fd1498Szrj 		}
114638fd1498Szrj 	    }
114738fd1498Szrj 	}
114838fd1498Szrj     }
114938fd1498Szrj   if (implicit_section && !get_section ())
115038fd1498Szrj     {
115138fd1498Szrj       error ("implicit_section flag is set but section isn't");
115238fd1498Szrj       error_found = true;
115338fd1498Szrj     }
115438fd1498Szrj   if (get_section () && get_comdat_group ()
115538fd1498Szrj       && !implicit_section
115638fd1498Szrj       && !lookup_attribute ("section", DECL_ATTRIBUTES (decl)))
115738fd1498Szrj     {
115838fd1498Szrj       error ("Both section and comdat group is set");
115938fd1498Szrj       error_found = true;
116038fd1498Szrj     }
116138fd1498Szrj   /* TODO: Add string table for sections, so we do not keep holding duplicated
116238fd1498Szrj      strings.  */
116338fd1498Szrj   if (alias && definition
116438fd1498Szrj       && get_section () != get_alias_target ()->get_section ()
116538fd1498Szrj       && (!get_section()
116638fd1498Szrj 	  || !get_alias_target ()->get_section ()
116738fd1498Szrj 	  || strcmp (get_section(),
116838fd1498Szrj 		     get_alias_target ()->get_section ())))
116938fd1498Szrj     {
117038fd1498Szrj       error ("Alias and target's section differs");
117138fd1498Szrj       get_alias_target ()->dump (stderr);
117238fd1498Szrj       error_found = true;
117338fd1498Szrj     }
117438fd1498Szrj   if (alias && definition
117538fd1498Szrj       && get_comdat_group () != get_alias_target ()->get_comdat_group ())
117638fd1498Szrj     {
117738fd1498Szrj       error ("Alias and target's comdat groups differs");
117838fd1498Szrj       get_alias_target ()->dump (stderr);
117938fd1498Szrj       error_found = true;
118038fd1498Szrj     }
118138fd1498Szrj   if (transparent_alias && definition && !weakref)
118238fd1498Szrj     {
118338fd1498Szrj       symtab_node *to = get_alias_target ();
118438fd1498Szrj       const char *name1
118538fd1498Szrj 	= IDENTIFIER_POINTER (
118638fd1498Szrj 	    ultimate_transparent_alias_target (DECL_ASSEMBLER_NAME (decl)));
118738fd1498Szrj       const char *name2
118838fd1498Szrj 	= IDENTIFIER_POINTER (
118938fd1498Szrj 	    ultimate_transparent_alias_target (DECL_ASSEMBLER_NAME (to->decl)));
119038fd1498Szrj       if (!symbol_table::assembler_names_equal_p (name1, name2))
119138fd1498Szrj 	{
119238fd1498Szrj 	  error ("Transparent alias and target's assembler names differs");
119338fd1498Szrj 	  get_alias_target ()->dump (stderr);
119438fd1498Szrj 	  error_found = true;
119538fd1498Szrj 	}
119638fd1498Szrj     }
119738fd1498Szrj   if (transparent_alias && definition
119838fd1498Szrj       && get_alias_target()->transparent_alias && get_alias_target()->analyzed)
119938fd1498Szrj     {
120038fd1498Szrj       error ("Chained transparent aliases");
120138fd1498Szrj       get_alias_target ()->dump (stderr);
120238fd1498Szrj       error_found = true;
120338fd1498Szrj     }
120438fd1498Szrj 
120538fd1498Szrj   return error_found;
120638fd1498Szrj }
120738fd1498Szrj 
120838fd1498Szrj /* Verify consistency of NODE.  */
120938fd1498Szrj 
121038fd1498Szrj DEBUG_FUNCTION void
verify(void)121138fd1498Szrj symtab_node::verify (void)
121238fd1498Szrj {
121338fd1498Szrj   if (seen_error ())
121438fd1498Szrj     return;
121538fd1498Szrj 
121638fd1498Szrj   timevar_push (TV_CGRAPH_VERIFY);
121738fd1498Szrj   if (cgraph_node *node = dyn_cast <cgraph_node *> (this))
121838fd1498Szrj     node->verify_node ();
121938fd1498Szrj   else
122038fd1498Szrj     if (verify_base ())
122138fd1498Szrj       {
122238fd1498Szrj 	debug ();
122338fd1498Szrj 	internal_error ("symtab_node::verify failed");
122438fd1498Szrj       }
122538fd1498Szrj   timevar_pop (TV_CGRAPH_VERIFY);
122638fd1498Szrj }
122738fd1498Szrj 
122838fd1498Szrj /* Verify symbol table for internal consistency.  */
122938fd1498Szrj 
123038fd1498Szrj DEBUG_FUNCTION void
verify_symtab_nodes(void)123138fd1498Szrj symtab_node::verify_symtab_nodes (void)
123238fd1498Szrj {
123338fd1498Szrj   symtab_node *node;
123438fd1498Szrj   hash_map<tree, symtab_node *> comdat_head_map (251);
123538fd1498Szrj 
123638fd1498Szrj   FOR_EACH_SYMBOL (node)
123738fd1498Szrj     {
123838fd1498Szrj       node->verify ();
123938fd1498Szrj       if (node->get_comdat_group ())
124038fd1498Szrj 	{
124138fd1498Szrj 	  symtab_node **entry, *s;
124238fd1498Szrj 	  bool existed;
124338fd1498Szrj 
124438fd1498Szrj 	  entry = &comdat_head_map.get_or_insert (node->get_comdat_group (),
124538fd1498Szrj 						  &existed);
124638fd1498Szrj 	  if (!existed)
124738fd1498Szrj 	    *entry = node;
124838fd1498Szrj 	  else if (!DECL_EXTERNAL (node->decl))
124938fd1498Szrj 	    {
125038fd1498Szrj 	      for (s = (*entry)->same_comdat_group;
125138fd1498Szrj 		   s != NULL && s != node && s != *entry;
125238fd1498Szrj 		   s = s->same_comdat_group)
125338fd1498Szrj 		;
125438fd1498Szrj 	      if (!s || s == *entry)
125538fd1498Szrj 		{
125638fd1498Szrj 		  error ("Two symbols with same comdat_group are not linked by "
125738fd1498Szrj 			 "the same_comdat_group list.");
125838fd1498Szrj 		  (*entry)->debug ();
125938fd1498Szrj 		  node->debug ();
126038fd1498Szrj 		  internal_error ("symtab_node::verify failed");
126138fd1498Szrj 		}
126238fd1498Szrj 	    }
126338fd1498Szrj 	}
126438fd1498Szrj     }
126538fd1498Szrj }
126638fd1498Szrj 
126738fd1498Szrj /* Make DECL local.  FIXME: We shouldn't need to mess with rtl this early,
126838fd1498Szrj    but other code such as notice_global_symbol generates rtl.  */
126938fd1498Szrj 
127038fd1498Szrj void
make_decl_local(void)127138fd1498Szrj symtab_node::make_decl_local (void)
127238fd1498Szrj {
127338fd1498Szrj   rtx rtl, symbol;
127438fd1498Szrj 
127538fd1498Szrj   if (weakref)
127638fd1498Szrj     {
127738fd1498Szrj       weakref = false;
127838fd1498Szrj       IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl)) = 0;
127938fd1498Szrj       TREE_CHAIN (DECL_ASSEMBLER_NAME (decl)) = NULL_TREE;
128038fd1498Szrj       symtab->change_decl_assembler_name
128138fd1498Szrj 	 (decl, DECL_ASSEMBLER_NAME (get_alias_target ()->decl));
128238fd1498Szrj       DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
128338fd1498Szrj 						 DECL_ATTRIBUTES (decl));
128438fd1498Szrj     }
128538fd1498Szrj   /* Avoid clearing comdat_groups on comdat-local decls.  */
128638fd1498Szrj   else if (TREE_PUBLIC (decl) == 0)
128738fd1498Szrj     return;
128838fd1498Szrj 
128938fd1498Szrj   /* Localizing a symbol also make all its transparent aliases local.  */
129038fd1498Szrj   ipa_ref *ref;
129138fd1498Szrj   for (unsigned i = 0; iterate_direct_aliases (i, ref); i++)
129238fd1498Szrj     {
129338fd1498Szrj       struct symtab_node *alias = ref->referring;
129438fd1498Szrj       if (alias->transparent_alias)
129538fd1498Szrj 	alias->make_decl_local ();
129638fd1498Szrj     }
129738fd1498Szrj 
129838fd1498Szrj   if (VAR_P (decl))
129938fd1498Szrj     {
130038fd1498Szrj       DECL_COMMON (decl) = 0;
130138fd1498Szrj       /* ADDRESSABLE flag is not defined for public symbols.  */
130238fd1498Szrj       TREE_ADDRESSABLE (decl) = 1;
130338fd1498Szrj       TREE_STATIC (decl) = 1;
130438fd1498Szrj     }
130538fd1498Szrj   else
130638fd1498Szrj     gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
130738fd1498Szrj 
130838fd1498Szrj   DECL_COMDAT (decl) = 0;
130938fd1498Szrj   DECL_WEAK (decl) = 0;
131038fd1498Szrj   DECL_EXTERNAL (decl) = 0;
131138fd1498Szrj   DECL_VISIBILITY_SPECIFIED (decl) = 0;
131238fd1498Szrj   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
131338fd1498Szrj   TREE_PUBLIC (decl) = 0;
131438fd1498Szrj   DECL_DLLIMPORT_P (decl) = 0;
131538fd1498Szrj   if (!DECL_RTL_SET_P (decl))
131638fd1498Szrj     return;
131738fd1498Szrj 
131838fd1498Szrj   /* Update rtl flags.  */
131938fd1498Szrj   make_decl_rtl (decl);
132038fd1498Szrj 
132138fd1498Szrj   rtl = DECL_RTL (decl);
132238fd1498Szrj   if (!MEM_P (rtl))
132338fd1498Szrj     return;
132438fd1498Szrj 
132538fd1498Szrj   symbol = XEXP (rtl, 0);
132638fd1498Szrj   if (GET_CODE (symbol) != SYMBOL_REF)
132738fd1498Szrj     return;
132838fd1498Szrj 
132938fd1498Szrj   SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
133038fd1498Szrj }
133138fd1498Szrj 
133238fd1498Szrj /* Copy visibility from N.
133338fd1498Szrj    This is useful when THIS becomes a transparent alias of N.  */
133438fd1498Szrj 
133538fd1498Szrj void
copy_visibility_from(symtab_node * n)133638fd1498Szrj symtab_node::copy_visibility_from (symtab_node *n)
133738fd1498Szrj {
133838fd1498Szrj   gcc_checking_assert (n->weakref == weakref);
133938fd1498Szrj 
134038fd1498Szrj   ipa_ref *ref;
134138fd1498Szrj   for (unsigned i = 0; iterate_direct_aliases (i, ref); i++)
134238fd1498Szrj     {
134338fd1498Szrj       struct symtab_node *alias = ref->referring;
134438fd1498Szrj       if (alias->transparent_alias)
134538fd1498Szrj 	alias->copy_visibility_from (n);
134638fd1498Szrj     }
134738fd1498Szrj 
134838fd1498Szrj   if (VAR_P (decl))
134938fd1498Szrj     {
135038fd1498Szrj       DECL_COMMON (decl) = DECL_COMMON (n->decl);
135138fd1498Szrj       /* ADDRESSABLE flag is not defined for public symbols.  */
135238fd1498Szrj       if (TREE_PUBLIC (decl) && !TREE_PUBLIC (n->decl))
135338fd1498Szrj         TREE_ADDRESSABLE (decl) = 1;
135438fd1498Szrj       TREE_STATIC (decl) = TREE_STATIC (n->decl);
135538fd1498Szrj     }
135638fd1498Szrj   else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
135738fd1498Szrj 
135838fd1498Szrj   DECL_COMDAT (decl) = DECL_COMDAT (n->decl);
135938fd1498Szrj   DECL_WEAK (decl) = DECL_WEAK (n->decl);
136038fd1498Szrj   DECL_EXTERNAL (decl) = DECL_EXTERNAL (n->decl);
136138fd1498Szrj   DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (n->decl);
136238fd1498Szrj   DECL_VISIBILITY (decl) = DECL_VISIBILITY (n->decl);
136338fd1498Szrj   TREE_PUBLIC (decl) = TREE_PUBLIC (n->decl);
136438fd1498Szrj   DECL_DLLIMPORT_P (decl) = DECL_DLLIMPORT_P (n->decl);
136538fd1498Szrj   resolution = n->resolution;
136638fd1498Szrj   set_comdat_group (n->get_comdat_group ());
136738fd1498Szrj   call_for_symbol_and_aliases (symtab_node::set_section,
136838fd1498Szrj 			     const_cast<char *>(n->get_section ()), true);
136938fd1498Szrj   externally_visible = n->externally_visible;
137038fd1498Szrj   if (!DECL_RTL_SET_P (decl))
137138fd1498Szrj     return;
137238fd1498Szrj 
137338fd1498Szrj   /* Update rtl flags.  */
137438fd1498Szrj   make_decl_rtl (decl);
137538fd1498Szrj 
137638fd1498Szrj   rtx rtl = DECL_RTL (decl);
137738fd1498Szrj   if (!MEM_P (rtl))
137838fd1498Szrj     return;
137938fd1498Szrj 
138038fd1498Szrj   rtx symbol = XEXP (rtl, 0);
138138fd1498Szrj   if (GET_CODE (symbol) != SYMBOL_REF)
138238fd1498Szrj     return;
138338fd1498Szrj 
138438fd1498Szrj   SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
138538fd1498Szrj }
138638fd1498Szrj 
138738fd1498Szrj /* Walk the alias chain to return the symbol NODE is alias of.
138838fd1498Szrj    If NODE is not an alias, return NODE.
138938fd1498Szrj    Assumes NODE is known to be alias.  */
139038fd1498Szrj 
139138fd1498Szrj symtab_node *
ultimate_alias_target_1(enum availability * availability,symtab_node * ref)139238fd1498Szrj symtab_node::ultimate_alias_target_1 (enum availability *availability,
139338fd1498Szrj 				      symtab_node *ref)
139438fd1498Szrj {
139538fd1498Szrj   bool transparent_p = false;
139638fd1498Szrj 
139738fd1498Szrj   /* To determine visibility of the target, we follow ELF semantic of aliases.
139838fd1498Szrj      Here alias is an alternative assembler name of a given definition. Its
139938fd1498Szrj      availability prevails the availability of its target (i.e. static alias of
140038fd1498Szrj      weak definition is available.
140138fd1498Szrj 
140238fd1498Szrj      Transaparent alias is just alternative anme of a given symbol used within
140338fd1498Szrj      one compilation unit and is translated prior hitting the object file.  It
140438fd1498Szrj      inherits the visibility of its target.
140538fd1498Szrj      Weakref is a different animal (and noweak definition is weak).
140638fd1498Szrj 
140738fd1498Szrj      If we ever get into supporting targets with different semantics, a target
140838fd1498Szrj      hook will be needed here.  */
140938fd1498Szrj 
141038fd1498Szrj   if (availability)
141138fd1498Szrj     {
141238fd1498Szrj       transparent_p = transparent_alias;
141338fd1498Szrj       if (!transparent_p)
141438fd1498Szrj 	*availability = get_availability (ref);
141538fd1498Szrj       else
141638fd1498Szrj 	*availability = AVAIL_NOT_AVAILABLE;
141738fd1498Szrj     }
141838fd1498Szrj 
141938fd1498Szrj   symtab_node *node = this;
142038fd1498Szrj   while (node)
142138fd1498Szrj     {
142238fd1498Szrj       if (node->alias && node->analyzed)
142338fd1498Szrj 	node = node->get_alias_target ();
142438fd1498Szrj       else
142538fd1498Szrj 	{
142638fd1498Szrj 	  if (!availability || (!transparent_p && node->analyzed))
142738fd1498Szrj 	    ;
142838fd1498Szrj 	  else if (node->analyzed && !node->transparent_alias)
142938fd1498Szrj 	    *availability = node->get_availability (ref);
143038fd1498Szrj 	  else
143138fd1498Szrj 	    *availability = AVAIL_NOT_AVAILABLE;
143238fd1498Szrj 	  return node;
143338fd1498Szrj 	}
143438fd1498Szrj       if (node && availability && transparent_p
143538fd1498Szrj 	  && node->transparent_alias)
143638fd1498Szrj 	{
143738fd1498Szrj 	  *availability = node->get_availability (ref);
143838fd1498Szrj 	  transparent_p = false;
143938fd1498Szrj 	}
144038fd1498Szrj     }
144138fd1498Szrj   if (availability)
144238fd1498Szrj     *availability = AVAIL_NOT_AVAILABLE;
144338fd1498Szrj   return NULL;
144438fd1498Szrj }
144538fd1498Szrj 
144638fd1498Szrj /* C++ FE sometimes change linkage flags after producing same body aliases.
144738fd1498Szrj 
144838fd1498Szrj    FIXME: C++ produce implicit aliases for virtual functions and vtables that
144938fd1498Szrj    are obviously equivalent.  The way it is doing so is however somewhat
145038fd1498Szrj    kludgy and interferes with the visibility code. As a result we need to
145138fd1498Szrj    copy the visibility from the target to get things right.  */
145238fd1498Szrj 
145338fd1498Szrj void
fixup_same_cpp_alias_visibility(symtab_node * target)145438fd1498Szrj symtab_node::fixup_same_cpp_alias_visibility (symtab_node *target)
145538fd1498Szrj {
145638fd1498Szrj   if (is_a <cgraph_node *> (this))
145738fd1498Szrj     {
145838fd1498Szrj       DECL_DECLARED_INLINE_P (decl)
145938fd1498Szrj 	 = DECL_DECLARED_INLINE_P (target->decl);
146038fd1498Szrj       DECL_DISREGARD_INLINE_LIMITS (decl)
146138fd1498Szrj 	 = DECL_DISREGARD_INLINE_LIMITS (target->decl);
146238fd1498Szrj     }
146338fd1498Szrj   /* FIXME: It is not really clear why those flags should not be copied for
146438fd1498Szrj      functions, too.  */
146538fd1498Szrj   else
146638fd1498Szrj     {
146738fd1498Szrj       DECL_WEAK (decl) = DECL_WEAK (target->decl);
146838fd1498Szrj       DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
146938fd1498Szrj       DECL_VISIBILITY (decl) = DECL_VISIBILITY (target->decl);
147038fd1498Szrj     }
147138fd1498Szrj   if (TREE_PUBLIC (decl))
147238fd1498Szrj     {
147338fd1498Szrj       tree group;
147438fd1498Szrj 
147538fd1498Szrj       DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
147638fd1498Szrj       DECL_COMDAT (decl) = DECL_COMDAT (target->decl);
147738fd1498Szrj       group = target->get_comdat_group ();
147838fd1498Szrj       set_comdat_group (group);
147938fd1498Szrj       if (group && !same_comdat_group)
148038fd1498Szrj 	add_to_same_comdat_group (target);
148138fd1498Szrj     }
148238fd1498Szrj   externally_visible = target->externally_visible;
148338fd1498Szrj }
148438fd1498Szrj 
148538fd1498Szrj /* Set section, do not recurse into aliases.
148638fd1498Szrj    When one wants to change section of a symbol and its aliases,
148738fd1498Szrj    use set_section.  */
148838fd1498Szrj 
148938fd1498Szrj void
set_section_for_node(const char * section)149038fd1498Szrj symtab_node::set_section_for_node (const char *section)
149138fd1498Szrj {
149238fd1498Szrj   const char *current = get_section ();
149338fd1498Szrj   section_hash_entry **slot;
149438fd1498Szrj 
149538fd1498Szrj   if (current == section
149638fd1498Szrj       || (current && section
149738fd1498Szrj 	  && !strcmp (current, section)))
149838fd1498Szrj     return;
149938fd1498Szrj 
150038fd1498Szrj   if (current)
150138fd1498Szrj     {
150238fd1498Szrj       x_section->ref_count--;
150338fd1498Szrj       if (!x_section->ref_count)
150438fd1498Szrj 	{
150538fd1498Szrj 	  hashval_t hash = htab_hash_string (x_section->name);
150638fd1498Szrj 	  slot = symtab->section_hash->find_slot_with_hash (x_section->name,
150738fd1498Szrj 							    hash, INSERT);
150838fd1498Szrj 	  ggc_free (x_section);
150938fd1498Szrj 	  symtab->section_hash->clear_slot (slot);
151038fd1498Szrj 	}
151138fd1498Szrj       x_section = NULL;
151238fd1498Szrj     }
151338fd1498Szrj   if (!section)
151438fd1498Szrj     {
151538fd1498Szrj       implicit_section = false;
151638fd1498Szrj       return;
151738fd1498Szrj     }
151838fd1498Szrj   if (!symtab->section_hash)
151938fd1498Szrj     symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
152038fd1498Szrj   slot = symtab->section_hash->find_slot_with_hash (section,
152138fd1498Szrj 						    htab_hash_string (section),
152238fd1498Szrj 						    INSERT);
152338fd1498Szrj   if (*slot)
152438fd1498Szrj     x_section = (section_hash_entry *)*slot;
152538fd1498Szrj   else
152638fd1498Szrj     {
152738fd1498Szrj       int len = strlen (section);
152838fd1498Szrj       *slot = x_section = ggc_cleared_alloc<section_hash_entry> ();
152938fd1498Szrj       x_section->name = ggc_vec_alloc<char> (len + 1);
153038fd1498Szrj       memcpy (x_section->name, section, len + 1);
153138fd1498Szrj     }
153238fd1498Szrj   x_section->ref_count++;
153338fd1498Szrj }
153438fd1498Szrj 
153538fd1498Szrj /* Worker for set_section.  */
153638fd1498Szrj 
153738fd1498Szrj bool
set_section(symtab_node * n,void * s)153838fd1498Szrj symtab_node::set_section (symtab_node *n, void *s)
153938fd1498Szrj {
154038fd1498Szrj   n->set_section_for_node ((char *)s);
154138fd1498Szrj   return false;
154238fd1498Szrj }
154338fd1498Szrj 
154438fd1498Szrj /* Set section of symbol and its aliases.  */
154538fd1498Szrj 
154638fd1498Szrj void
set_section(const char * section)154738fd1498Szrj symtab_node::set_section (const char *section)
154838fd1498Szrj {
154938fd1498Szrj   gcc_assert (!this->alias);
155038fd1498Szrj   call_for_symbol_and_aliases
155138fd1498Szrj     (symtab_node::set_section, const_cast<char *>(section), true);
155238fd1498Szrj }
155338fd1498Szrj 
155438fd1498Szrj /* Return the initialization priority.  */
155538fd1498Szrj 
155638fd1498Szrj priority_type
get_init_priority()155738fd1498Szrj symtab_node::get_init_priority ()
155838fd1498Szrj {
155938fd1498Szrj   if (!this->in_init_priority_hash)
156038fd1498Szrj     return DEFAULT_INIT_PRIORITY;
156138fd1498Szrj 
156238fd1498Szrj   symbol_priority_map *h = symtab->init_priority_hash->get (this);
156338fd1498Szrj   return h ? h->init : DEFAULT_INIT_PRIORITY;
156438fd1498Szrj }
156538fd1498Szrj 
156638fd1498Szrj /* Return the finalization priority.  */
156738fd1498Szrj 
156838fd1498Szrj priority_type
get_fini_priority()156938fd1498Szrj cgraph_node::get_fini_priority ()
157038fd1498Szrj {
157138fd1498Szrj   if (!this->in_init_priority_hash)
157238fd1498Szrj     return DEFAULT_INIT_PRIORITY;
157338fd1498Szrj   symbol_priority_map *h = symtab->init_priority_hash->get (this);
157438fd1498Szrj   return h ? h->fini : DEFAULT_INIT_PRIORITY;
157538fd1498Szrj }
157638fd1498Szrj 
157738fd1498Szrj /* Return the initialization and finalization priority information for
157838fd1498Szrj    DECL.  If there is no previous priority information, a freshly
157938fd1498Szrj    allocated structure is returned.  */
158038fd1498Szrj 
158138fd1498Szrj symbol_priority_map *
priority_info(void)158238fd1498Szrj symtab_node::priority_info (void)
158338fd1498Szrj {
158438fd1498Szrj   if (!symtab->init_priority_hash)
158538fd1498Szrj     symtab->init_priority_hash = hash_map<symtab_node *, symbol_priority_map>::create_ggc (13);
158638fd1498Szrj 
158738fd1498Szrj   bool existed;
158838fd1498Szrj   symbol_priority_map *h
158938fd1498Szrj     = &symtab->init_priority_hash->get_or_insert (this, &existed);
159038fd1498Szrj   if (!existed)
159138fd1498Szrj     {
159238fd1498Szrj       h->init = DEFAULT_INIT_PRIORITY;
159338fd1498Szrj       h->fini = DEFAULT_INIT_PRIORITY;
159438fd1498Szrj       in_init_priority_hash = true;
159538fd1498Szrj     }
159638fd1498Szrj 
159738fd1498Szrj   return h;
159838fd1498Szrj }
159938fd1498Szrj 
160038fd1498Szrj /* Set initialization priority to PRIORITY.  */
160138fd1498Szrj 
160238fd1498Szrj void
set_init_priority(priority_type priority)160338fd1498Szrj symtab_node::set_init_priority (priority_type priority)
160438fd1498Szrj {
160538fd1498Szrj   symbol_priority_map *h;
160638fd1498Szrj 
160738fd1498Szrj   if (is_a <cgraph_node *> (this))
160838fd1498Szrj     gcc_assert (DECL_STATIC_CONSTRUCTOR (this->decl));
160938fd1498Szrj 
161038fd1498Szrj   if (priority == DEFAULT_INIT_PRIORITY)
161138fd1498Szrj     {
161238fd1498Szrj       gcc_assert (get_init_priority() == priority);
161338fd1498Szrj       return;
161438fd1498Szrj     }
161538fd1498Szrj   h = priority_info ();
161638fd1498Szrj   h->init = priority;
161738fd1498Szrj }
161838fd1498Szrj 
161938fd1498Szrj /* Set fialization priority to PRIORITY.  */
162038fd1498Szrj 
162138fd1498Szrj void
set_fini_priority(priority_type priority)162238fd1498Szrj cgraph_node::set_fini_priority (priority_type priority)
162338fd1498Szrj {
162438fd1498Szrj   symbol_priority_map *h;
162538fd1498Szrj 
162638fd1498Szrj   gcc_assert (DECL_STATIC_DESTRUCTOR (this->decl));
162738fd1498Szrj 
162838fd1498Szrj   if (priority == DEFAULT_INIT_PRIORITY)
162938fd1498Szrj     {
163038fd1498Szrj       gcc_assert (get_fini_priority() == priority);
163138fd1498Szrj       return;
163238fd1498Szrj     }
163338fd1498Szrj   h = priority_info ();
163438fd1498Szrj   h->fini = priority;
163538fd1498Szrj }
163638fd1498Szrj 
163738fd1498Szrj /* Worker for symtab_resolve_alias.  */
163838fd1498Szrj 
163938fd1498Szrj bool
set_implicit_section(symtab_node * n,void * data ATTRIBUTE_UNUSED)164038fd1498Szrj symtab_node::set_implicit_section (symtab_node *n,
164138fd1498Szrj 				   void *data ATTRIBUTE_UNUSED)
164238fd1498Szrj {
164338fd1498Szrj   n->implicit_section = true;
164438fd1498Szrj   return false;
164538fd1498Szrj }
164638fd1498Szrj 
164738fd1498Szrj /* Add reference recording that symtab node is alias of TARGET.
164838fd1498Szrj    The function can fail in the case of aliasing cycles; in this case
164938fd1498Szrj    it returns false.  */
165038fd1498Szrj 
165138fd1498Szrj bool
resolve_alias(symtab_node * target,bool transparent)165238fd1498Szrj symtab_node::resolve_alias (symtab_node *target, bool transparent)
165338fd1498Szrj {
165438fd1498Szrj   symtab_node *n;
165538fd1498Szrj 
165638fd1498Szrj   gcc_assert (!analyzed && !vec_safe_length (ref_list.references));
165738fd1498Szrj 
165838fd1498Szrj   /* Never let cycles to creep into the symbol table alias references;
165938fd1498Szrj      those will make alias walkers to be infinite.  */
166038fd1498Szrj   for (n = target; n && n->alias;
166138fd1498Szrj        n = n->analyzed ? n->get_alias_target () : NULL)
166238fd1498Szrj     if (n == this)
166338fd1498Szrj        {
166438fd1498Szrj 	 if (is_a <cgraph_node *> (this))
166538fd1498Szrj 	   error ("function %q+D part of alias cycle", decl);
166638fd1498Szrj 	 else if (is_a <varpool_node *> (this))
166738fd1498Szrj 	   error ("variable %q+D part of alias cycle", decl);
166838fd1498Szrj 	 else
166938fd1498Szrj 	   gcc_unreachable ();
167038fd1498Szrj 	 alias = false;
167138fd1498Szrj 	 return false;
167238fd1498Szrj        }
167338fd1498Szrj 
167438fd1498Szrj   /* "analyze" the node - i.e. mark the reference.  */
167538fd1498Szrj   definition = true;
167638fd1498Szrj   alias = true;
167738fd1498Szrj   analyzed = true;
167838fd1498Szrj   transparent |= transparent_alias;
167938fd1498Szrj   transparent_alias = transparent;
168038fd1498Szrj   if (transparent)
168138fd1498Szrj     while (target->transparent_alias && target->analyzed)
168238fd1498Szrj       target = target->get_alias_target ();
168338fd1498Szrj   create_reference (target, IPA_REF_ALIAS, NULL);
168438fd1498Szrj 
168538fd1498Szrj   /* Add alias into the comdat group of its target unless it is already there.  */
168638fd1498Szrj   if (same_comdat_group)
168738fd1498Szrj     remove_from_same_comdat_group ();
168838fd1498Szrj   set_comdat_group (NULL);
168938fd1498Szrj   if (target->get_comdat_group ())
169038fd1498Szrj     add_to_same_comdat_group (target);
169138fd1498Szrj 
169238fd1498Szrj   if ((get_section () != target->get_section ()
169338fd1498Szrj        || target->get_comdat_group ()) && get_section () && !implicit_section)
169438fd1498Szrj     {
169538fd1498Szrj       error ("section of alias %q+D must match section of its target", decl);
169638fd1498Szrj     }
169738fd1498Szrj   call_for_symbol_and_aliases (symtab_node::set_section,
169838fd1498Szrj 			     const_cast<char *>(target->get_section ()), true);
169938fd1498Szrj   if (target->implicit_section)
170038fd1498Szrj     call_for_symbol_and_aliases (set_implicit_section, NULL, true);
170138fd1498Szrj 
170238fd1498Szrj   /* Alias targets become redundant after alias is resolved into an reference.
170338fd1498Szrj      We do not want to keep it around or we would have to mind updating them
170438fd1498Szrj      when renaming symbols.  */
170538fd1498Szrj   alias_target = NULL;
170638fd1498Szrj 
170738fd1498Szrj   if (!transparent && cpp_implicit_alias && symtab->state >= CONSTRUCTION)
170838fd1498Szrj     fixup_same_cpp_alias_visibility (target);
170938fd1498Szrj 
171038fd1498Szrj   /* If alias has address taken, so does the target.  */
171138fd1498Szrj   if (address_taken)
171238fd1498Szrj     target->ultimate_alias_target ()->address_taken = true;
171338fd1498Szrj 
171438fd1498Szrj   /* All non-transparent aliases of THIS are now in fact aliases of TARGET.
171538fd1498Szrj      If alias is transparent, also all transparent aliases of THIS are now
171638fd1498Szrj      aliases of TARGET.
171738fd1498Szrj      Also merge same comdat group lists.  */
171838fd1498Szrj   ipa_ref *ref;
171938fd1498Szrj   for (unsigned i = 0; iterate_direct_aliases (i, ref);)
172038fd1498Szrj     {
172138fd1498Szrj       struct symtab_node *alias_alias = ref->referring;
172238fd1498Szrj       if (alias_alias->get_comdat_group ())
172338fd1498Szrj 	{
172438fd1498Szrj 	  alias_alias->remove_from_same_comdat_group ();
172538fd1498Szrj 	  alias_alias->set_comdat_group (NULL);
172638fd1498Szrj 	  if (target->get_comdat_group ())
172738fd1498Szrj 	    alias_alias->add_to_same_comdat_group (target);
172838fd1498Szrj 	}
172938fd1498Szrj       if (!alias_alias->transparent_alias || transparent)
173038fd1498Szrj 	{
173138fd1498Szrj 	  alias_alias->remove_all_references ();
173238fd1498Szrj 	  alias_alias->create_reference (target, IPA_REF_ALIAS, NULL);
173338fd1498Szrj 	}
173438fd1498Szrj       else i++;
173538fd1498Szrj     }
173638fd1498Szrj   return true;
173738fd1498Szrj }
173838fd1498Szrj 
173938fd1498Szrj /* Worker searching noninterposable alias.  */
174038fd1498Szrj 
174138fd1498Szrj bool
noninterposable_alias(symtab_node * node,void * data)174238fd1498Szrj symtab_node::noninterposable_alias (symtab_node *node, void *data)
174338fd1498Szrj {
174438fd1498Szrj   if (!node->transparent_alias && decl_binds_to_current_def_p (node->decl))
174538fd1498Szrj     {
174638fd1498Szrj       symtab_node *fn = node->ultimate_alias_target ();
174738fd1498Szrj 
174838fd1498Szrj       /* Ensure that the alias is well formed this may not be the case
174938fd1498Szrj 	 of user defined aliases and currently it is not always the case
175038fd1498Szrj 	 of C++ same body aliases (that is a bug).  */
175138fd1498Szrj       if (TREE_TYPE (node->decl) != TREE_TYPE (fn->decl)
175238fd1498Szrj 	  || DECL_CONTEXT (node->decl) != DECL_CONTEXT (fn->decl)
175338fd1498Szrj 	  || (TREE_CODE (node->decl) == FUNCTION_DECL
175438fd1498Szrj 	      && flags_from_decl_or_type (node->decl)
175538fd1498Szrj 		 != flags_from_decl_or_type (fn->decl))
175638fd1498Szrj 	  || DECL_ATTRIBUTES (node->decl) != DECL_ATTRIBUTES (fn->decl))
175738fd1498Szrj 	return false;
175838fd1498Szrj       *(symtab_node **)data = node;
175938fd1498Szrj       return true;
176038fd1498Szrj     }
176138fd1498Szrj   return false;
176238fd1498Szrj }
176338fd1498Szrj 
176438fd1498Szrj /* If node can not be overwriten by static or dynamic linker to point to
176538fd1498Szrj    different definition, return NODE. Otherwise look for alias with such
176638fd1498Szrj    property and if none exists, introduce new one.  */
176738fd1498Szrj 
176838fd1498Szrj symtab_node *
noninterposable_alias(void)176938fd1498Szrj symtab_node::noninterposable_alias (void)
177038fd1498Szrj {
177138fd1498Szrj   tree new_decl;
177238fd1498Szrj   symtab_node *new_node = NULL;
177338fd1498Szrj 
177438fd1498Szrj   /* First try to look up existing alias or base object
177538fd1498Szrj      (if that is already non-overwritable).  */
177638fd1498Szrj   symtab_node *node = ultimate_alias_target ();
177738fd1498Szrj   gcc_assert (!node->alias && !node->weakref);
177838fd1498Szrj   node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias,
177938fd1498Szrj 				   (void *)&new_node, true);
178038fd1498Szrj   if (new_node)
178138fd1498Szrj     return new_node;
178238fd1498Szrj 
178338fd1498Szrj   /* If aliases aren't supported by the assembler, fail.  */
178438fd1498Szrj   if (!TARGET_SUPPORTS_ALIASES)
178538fd1498Szrj     return NULL;
178638fd1498Szrj 
178738fd1498Szrj   /* Otherwise create a new one.  */
178838fd1498Szrj   new_decl = copy_node (node->decl);
178938fd1498Szrj   DECL_DLLIMPORT_P (new_decl) = 0;
179038fd1498Szrj   DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias");
179138fd1498Szrj   if (TREE_CODE (new_decl) == FUNCTION_DECL)
179238fd1498Szrj     DECL_STRUCT_FUNCTION (new_decl) = NULL;
179338fd1498Szrj   DECL_INITIAL (new_decl) = NULL;
179438fd1498Szrj   SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
179538fd1498Szrj   SET_DECL_RTL (new_decl, NULL);
179638fd1498Szrj 
179738fd1498Szrj   /* Update the properties.  */
179838fd1498Szrj   DECL_EXTERNAL (new_decl) = 0;
179938fd1498Szrj   TREE_PUBLIC (new_decl) = 0;
180038fd1498Szrj   DECL_COMDAT (new_decl) = 0;
180138fd1498Szrj   DECL_WEAK (new_decl) = 0;
180238fd1498Szrj 
180338fd1498Szrj   /* Since the aliases can be added to vtables, keep DECL_VIRTUAL flag.  */
180438fd1498Szrj   DECL_VIRTUAL_P (new_decl) = DECL_VIRTUAL_P (node->decl);
180538fd1498Szrj   if (TREE_CODE (new_decl) == FUNCTION_DECL)
180638fd1498Szrj     {
180738fd1498Szrj       DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
180838fd1498Szrj       DECL_STATIC_DESTRUCTOR (new_decl) = 0;
180938fd1498Szrj       new_node = cgraph_node::create_alias (new_decl, node->decl);
181038fd1498Szrj     }
181138fd1498Szrj   else
181238fd1498Szrj     {
181338fd1498Szrj       TREE_READONLY (new_decl) = TREE_READONLY (node->decl);
181438fd1498Szrj       DECL_INITIAL (new_decl) = error_mark_node;
181538fd1498Szrj       new_node = varpool_node::create_alias (new_decl, node->decl);
181638fd1498Szrj     }
181738fd1498Szrj   new_node->resolve_alias (node);
181838fd1498Szrj   gcc_assert (decl_binds_to_current_def_p (new_decl)
181938fd1498Szrj 	      && targetm.binds_local_p (new_decl));
182038fd1498Szrj   return new_node;
182138fd1498Szrj }
182238fd1498Szrj 
182338fd1498Szrj /* Return true if symtab node and TARGET represents
182438fd1498Szrj    semantically equivalent symbols.  */
182538fd1498Szrj 
182638fd1498Szrj bool
semantically_equivalent_p(symtab_node * target)182738fd1498Szrj symtab_node::semantically_equivalent_p (symtab_node *target)
182838fd1498Szrj {
182938fd1498Szrj   enum availability avail;
183038fd1498Szrj   symtab_node *ba;
183138fd1498Szrj   symtab_node *bb;
183238fd1498Szrj 
183338fd1498Szrj   /* Equivalent functions are equivalent.  */
183438fd1498Szrj   if (decl == target->decl)
183538fd1498Szrj     return true;
183638fd1498Szrj 
183738fd1498Szrj   /* If symbol is not overwritable by different implementation,
183838fd1498Szrj      walk to the base object it defines.  */
183938fd1498Szrj   ba = ultimate_alias_target (&avail);
184038fd1498Szrj   if (avail >= AVAIL_AVAILABLE)
184138fd1498Szrj     {
184238fd1498Szrj       if (target == ba)
184338fd1498Szrj 	return true;
184438fd1498Szrj     }
184538fd1498Szrj   else
184638fd1498Szrj     ba = this;
184738fd1498Szrj   bb = target->ultimate_alias_target (&avail);
184838fd1498Szrj   if (avail >= AVAIL_AVAILABLE)
184938fd1498Szrj     {
185038fd1498Szrj       if (this == bb)
185138fd1498Szrj 	return true;
185238fd1498Szrj     }
185338fd1498Szrj   else
185438fd1498Szrj     bb = target;
185538fd1498Szrj   return bb == ba;
185638fd1498Szrj }
185738fd1498Szrj 
185838fd1498Szrj /* Classify symbol symtab node for partitioning.  */
185938fd1498Szrj 
186038fd1498Szrj enum symbol_partitioning_class
get_partitioning_class(void)186138fd1498Szrj symtab_node::get_partitioning_class (void)
186238fd1498Szrj {
186338fd1498Szrj   /* Inline clones are always duplicated.
186438fd1498Szrj      This include external delcarations.   */
186538fd1498Szrj   cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
186638fd1498Szrj 
186738fd1498Szrj   if (DECL_ABSTRACT_P (decl))
186838fd1498Szrj     return SYMBOL_EXTERNAL;
186938fd1498Szrj 
187038fd1498Szrj   if (cnode && cnode->global.inlined_to)
187138fd1498Szrj     return SYMBOL_DUPLICATE;
187238fd1498Szrj 
187338fd1498Szrj   /* Transparent aliases are always duplicated.  */
187438fd1498Szrj   if (transparent_alias)
187538fd1498Szrj     return definition ? SYMBOL_DUPLICATE : SYMBOL_EXTERNAL;
187638fd1498Szrj 
187738fd1498Szrj   /* External declarations are external.  */
187838fd1498Szrj   if (DECL_EXTERNAL (decl))
187938fd1498Szrj     return SYMBOL_EXTERNAL;
188038fd1498Szrj 
188138fd1498Szrj   if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
188238fd1498Szrj     {
188338fd1498Szrj       if (alias && definition && !ultimate_alias_target ()->definition)
188438fd1498Szrj 	return SYMBOL_EXTERNAL;
188538fd1498Szrj       /* Constant pool references use local symbol names that can not
188638fd1498Szrj          be promoted global.  We should never put into a constant pool
188738fd1498Szrj          objects that can not be duplicated across partitions.  */
188838fd1498Szrj       if (DECL_IN_CONSTANT_POOL (decl))
188938fd1498Szrj 	return SYMBOL_DUPLICATE;
189038fd1498Szrj       if (DECL_HARD_REGISTER (decl))
189138fd1498Szrj 	return SYMBOL_DUPLICATE;
189238fd1498Szrj       gcc_checking_assert (vnode->definition);
189338fd1498Szrj     }
189438fd1498Szrj   /* Functions that are cloned may stay in callgraph even if they are unused.
189538fd1498Szrj      Handle them as external; compute_ltrans_boundary take care to make
189638fd1498Szrj      proper things to happen (i.e. to make them appear in the boundary but
189738fd1498Szrj      with body streamed, so clone can me materialized).  */
189838fd1498Szrj   else if (!dyn_cast <cgraph_node *> (this)->function_symbol ()->definition)
189938fd1498Szrj     return SYMBOL_EXTERNAL;
190038fd1498Szrj 
190138fd1498Szrj   /* Linker discardable symbols are duplicated to every use unless they are
190238fd1498Szrj      keyed.  */
190338fd1498Szrj   if (DECL_ONE_ONLY (decl)
190438fd1498Szrj       && !force_output
190538fd1498Szrj       && !forced_by_abi
190638fd1498Szrj       && !used_from_object_file_p ())
190738fd1498Szrj     return SYMBOL_DUPLICATE;
190838fd1498Szrj 
190938fd1498Szrj   return SYMBOL_PARTITION;
191038fd1498Szrj }
191138fd1498Szrj 
191238fd1498Szrj /* Return true when symbol is known to be non-zero.  */
191338fd1498Szrj 
191438fd1498Szrj bool
nonzero_address()191538fd1498Szrj symtab_node::nonzero_address ()
191638fd1498Szrj {
191738fd1498Szrj   /* Weakrefs may be NULL when their target is not defined.  */
191838fd1498Szrj   if (alias && weakref)
191938fd1498Szrj     {
192038fd1498Szrj       if (analyzed)
192138fd1498Szrj 	{
192238fd1498Szrj 	  symtab_node *target = ultimate_alias_target ();
192338fd1498Szrj 
192438fd1498Szrj 	  if (target->alias && target->weakref)
192538fd1498Szrj 	    return false;
192638fd1498Szrj 	  /* We can not recurse to target::nonzero.  It is possible that the
192738fd1498Szrj 	     target is used only via the alias.
192838fd1498Szrj 	     We may walk references and look for strong use, but we do not know
192938fd1498Szrj 	     if this strong use will survive to final binary, so be
193038fd1498Szrj 	     conservative here.
193138fd1498Szrj 	     ??? Maybe we could do the lookup during late optimization that
193238fd1498Szrj 	     could be useful to eliminate the NULL pointer checks in LTO
193338fd1498Szrj 	     programs.  */
193438fd1498Szrj 	  if (target->definition && !DECL_EXTERNAL (target->decl))
193538fd1498Szrj 	      return true;
193638fd1498Szrj 	  if (target->resolution != LDPR_UNKNOWN
193738fd1498Szrj 	      && target->resolution != LDPR_UNDEF
193838fd1498Szrj 	      && !target->can_be_discarded_p ()
193938fd1498Szrj 	      && flag_delete_null_pointer_checks)
194038fd1498Szrj 	    return true;
194138fd1498Szrj 	  return false;
194238fd1498Szrj 	}
194338fd1498Szrj       else
194438fd1498Szrj         return false;
194538fd1498Szrj     }
194638fd1498Szrj 
194738fd1498Szrj   /* With !flag_delete_null_pointer_checks we assume that symbols may
194838fd1498Szrj      bind to NULL. This is on by default on embedded targets only.
194938fd1498Szrj 
195038fd1498Szrj      Otherwise all non-WEAK symbols must be defined and thus non-NULL or
195138fd1498Szrj      linking fails.  Important case of WEAK we want to do well are comdats.
195238fd1498Szrj      Those are handled by later check for definition.
195338fd1498Szrj 
195438fd1498Szrj      When parsing, beware the cases when WEAK attribute is added later.  */
195538fd1498Szrj   if (!DECL_WEAK (decl)
195638fd1498Szrj       && flag_delete_null_pointer_checks)
195738fd1498Szrj     {
195838fd1498Szrj       refuse_visibility_changes = true;
195938fd1498Szrj       return true;
196038fd1498Szrj     }
196138fd1498Szrj 
1962*58e805e6Szrj   /* If target is defined and either comdat or not extern, we know it will be
1963*58e805e6Szrj      output and thus it will bind to non-NULL.
1964*58e805e6Szrj      Play safe for flag_delete_null_pointer_checks where weak definition may
196538fd1498Szrj      be re-defined by NULL.  */
1966*58e805e6Szrj   if (definition && (!DECL_EXTERNAL (decl) || DECL_COMDAT (decl))
196738fd1498Szrj       && (flag_delete_null_pointer_checks || !DECL_WEAK (decl)))
196838fd1498Szrj     {
196938fd1498Szrj       if (!DECL_WEAK (decl))
197038fd1498Szrj         refuse_visibility_changes = true;
197138fd1498Szrj       return true;
197238fd1498Szrj     }
197338fd1498Szrj 
197438fd1498Szrj   /* As the last resort, check the resolution info.  */
197538fd1498Szrj   if (resolution != LDPR_UNKNOWN
197638fd1498Szrj       && resolution != LDPR_UNDEF
197738fd1498Szrj       && !can_be_discarded_p ()
197838fd1498Szrj       && flag_delete_null_pointer_checks)
197938fd1498Szrj     return true;
198038fd1498Szrj   return false;
198138fd1498Szrj }
198238fd1498Szrj 
198338fd1498Szrj /* Return 0 if symbol is known to have different address than S2,
198438fd1498Szrj    Return 1 if symbol is known to have same address as S2,
198538fd1498Szrj    return -1 otherwise.
198638fd1498Szrj 
198738fd1498Szrj    If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
198838fd1498Szrj    and S2 is going to be accessed.  This eliminates the situations when
198938fd1498Szrj    either THIS or S2 is NULL and is seful for comparing bases when deciding
199038fd1498Szrj    about memory aliasing.  */
199138fd1498Szrj int
equal_address_to(symtab_node * s2,bool memory_accessed)199238fd1498Szrj symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
199338fd1498Szrj {
199438fd1498Szrj   enum availability avail1, avail2;
199538fd1498Szrj 
199638fd1498Szrj   /* A Shortcut: equivalent symbols are always equivalent.  */
199738fd1498Szrj   if (this == s2)
199838fd1498Szrj     return 1;
199938fd1498Szrj 
200038fd1498Szrj   /* Unwind transparent aliases first; those are always equal to their
200138fd1498Szrj      target.  */
200238fd1498Szrj   if (this->transparent_alias && this->analyzed)
200338fd1498Szrj     return this->get_alias_target ()->equal_address_to (s2);
200438fd1498Szrj   while (s2->transparent_alias && s2->analyzed)
200538fd1498Szrj     s2 = s2->get_alias_target();
200638fd1498Szrj 
200738fd1498Szrj   if (this == s2)
200838fd1498Szrj     return 1;
200938fd1498Szrj 
201038fd1498Szrj   /* For non-interposable aliases, lookup and compare their actual definitions.
201138fd1498Szrj      Also check if the symbol needs to bind to given definition.  */
201238fd1498Szrj   symtab_node *rs1 = ultimate_alias_target (&avail1);
201338fd1498Szrj   symtab_node *rs2 = s2->ultimate_alias_target (&avail2);
201438fd1498Szrj   bool binds_local1 = rs1->analyzed && decl_binds_to_current_def_p (this->decl);
201538fd1498Szrj   bool binds_local2 = rs2->analyzed && decl_binds_to_current_def_p (s2->decl);
201638fd1498Szrj   bool really_binds_local1 = binds_local1;
201738fd1498Szrj   bool really_binds_local2 = binds_local2;
201838fd1498Szrj 
201938fd1498Szrj   /* Addresses of vtables and virtual functions can not be used by user
202038fd1498Szrj      code and are used only within speculation.  In this case we may make
202138fd1498Szrj      symbol equivalent to its alias even if interposition may break this
202238fd1498Szrj      rule.  Doing so will allow us to turn speculative inlining into
202338fd1498Szrj      non-speculative more agressively.  */
202438fd1498Szrj   if (DECL_VIRTUAL_P (this->decl) && avail1 >= AVAIL_AVAILABLE)
202538fd1498Szrj     binds_local1 = true;
202638fd1498Szrj   if (DECL_VIRTUAL_P (s2->decl) && avail2 >= AVAIL_AVAILABLE)
202738fd1498Szrj     binds_local2 = true;
202838fd1498Szrj 
202938fd1498Szrj   /* If both definitions are available we know that even if they are bound
203038fd1498Szrj      to other unit they must be defined same way and therefore we can use
203138fd1498Szrj      equivalence test.  */
203238fd1498Szrj   if (rs1 != rs2 && avail1 >= AVAIL_AVAILABLE && avail2 >= AVAIL_AVAILABLE)
203338fd1498Szrj     binds_local1 = binds_local2 = true;
203438fd1498Szrj 
203538fd1498Szrj   if (binds_local1 && binds_local2 && rs1 == rs2)
203638fd1498Szrj     {
203738fd1498Szrj       /* We made use of the fact that alias is not weak.  */
203838fd1498Szrj       if (rs1 != this)
203938fd1498Szrj         refuse_visibility_changes = true;
204038fd1498Szrj       if (rs2 != s2)
204138fd1498Szrj         s2->refuse_visibility_changes = true;
204238fd1498Szrj       return 1;
204338fd1498Szrj     }
204438fd1498Szrj 
204538fd1498Szrj   /* If both symbols may resolve to NULL, we can not really prove them
204638fd1498Szrj      different.  */
204738fd1498Szrj   if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ())
204838fd1498Szrj     return -1;
204938fd1498Szrj 
205038fd1498Szrj   /* Except for NULL, functions and variables never overlap.  */
205138fd1498Szrj   if (TREE_CODE (decl) != TREE_CODE (s2->decl))
205238fd1498Szrj     return 0;
205338fd1498Szrj 
205438fd1498Szrj   /* If one of the symbols is unresolved alias, punt.  */
205538fd1498Szrj   if (rs1->alias || rs2->alias)
205638fd1498Szrj     return -1;
205738fd1498Szrj 
205838fd1498Szrj   /* If we have a non-interposale definition of at least one of the symbols
205938fd1498Szrj      and the other symbol is different, we know other unit can not interpose
206038fd1498Szrj      it to the first symbol; all aliases of the definition needs to be
206138fd1498Szrj      present in the current unit.  */
206238fd1498Szrj   if (((really_binds_local1 || really_binds_local2)
206338fd1498Szrj       /* If we have both definitions and they are different, we know they
206438fd1498Szrj 	 will be different even in units they binds to.  */
206538fd1498Szrj        || (binds_local1 && binds_local2))
206638fd1498Szrj       && rs1 != rs2)
206738fd1498Szrj     {
206838fd1498Szrj       /* We make use of the fact that one symbol is not alias of the other
206938fd1498Szrj 	 and that the definition is non-interposable.  */
207038fd1498Szrj       refuse_visibility_changes = true;
207138fd1498Szrj       s2->refuse_visibility_changes = true;
207238fd1498Szrj       rs1->refuse_visibility_changes = true;
207338fd1498Szrj       rs2->refuse_visibility_changes = true;
207438fd1498Szrj       return 0;
207538fd1498Szrj     }
207638fd1498Szrj 
207738fd1498Szrj   /* TODO: Alias oracle basically assume that addresses of global variables
207838fd1498Szrj      are different unless they are declared as alias of one to another while
207938fd1498Szrj      the code folding comparsions doesn't.
208038fd1498Szrj      We probably should be consistent and use this fact here, too, but for
208138fd1498Szrj      the moment return false only when we are called from the alias oracle.  */
208238fd1498Szrj 
208338fd1498Szrj   return memory_accessed && rs1 != rs2 ? 0 : -1;
208438fd1498Szrj }
208538fd1498Szrj 
208638fd1498Szrj /* Worker for call_for_symbol_and_aliases.  */
208738fd1498Szrj 
208838fd1498Szrj bool
call_for_symbol_and_aliases_1(bool (* callback)(symtab_node *,void *),void * data,bool include_overwritable)208938fd1498Szrj symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *,
209038fd1498Szrj 							      void *),
209138fd1498Szrj 					    void *data,
209238fd1498Szrj 					    bool include_overwritable)
209338fd1498Szrj {
209438fd1498Szrj   ipa_ref *ref;
209538fd1498Szrj   FOR_EACH_ALIAS (this, ref)
209638fd1498Szrj     {
209738fd1498Szrj       symtab_node *alias = ref->referring;
209838fd1498Szrj       if (include_overwritable
209938fd1498Szrj 	  || alias->get_availability () > AVAIL_INTERPOSABLE)
210038fd1498Szrj 	if (alias->call_for_symbol_and_aliases (callback, data,
210138fd1498Szrj 					      include_overwritable))
210238fd1498Szrj 	  return true;
210338fd1498Szrj     }
210438fd1498Szrj   return false;
210538fd1498Szrj }
210638fd1498Szrj 
210738fd1498Szrj /* Return true if address of N is possibly compared.  */
210838fd1498Szrj 
210938fd1498Szrj static bool
address_matters_1(symtab_node * n,void *)211038fd1498Szrj address_matters_1 (symtab_node *n, void *)
211138fd1498Szrj {
211238fd1498Szrj   struct ipa_ref *ref;
211338fd1498Szrj 
211438fd1498Szrj   if (!n->address_can_be_compared_p ())
211538fd1498Szrj     return false;
211638fd1498Szrj   if (n->externally_visible || n->force_output)
211738fd1498Szrj     return true;
211838fd1498Szrj 
211938fd1498Szrj   for (unsigned int i = 0; n->iterate_referring (i, ref); i++)
212038fd1498Szrj     if (ref->address_matters_p ())
212138fd1498Szrj       return true;
212238fd1498Szrj   return false;
212338fd1498Szrj }
212438fd1498Szrj 
212538fd1498Szrj /* Return true if symbol's address may possibly be compared to other
212638fd1498Szrj    symbol's address.  */
212738fd1498Szrj 
212838fd1498Szrj bool
address_matters_p()212938fd1498Szrj symtab_node::address_matters_p ()
213038fd1498Szrj {
213138fd1498Szrj   gcc_assert (!alias);
213238fd1498Szrj   return call_for_symbol_and_aliases (address_matters_1, NULL, true);
213338fd1498Szrj }
213438fd1498Szrj 
213538fd1498Szrj /* Return true if symbol's alignment may be increased.  */
213638fd1498Szrj 
213738fd1498Szrj bool
can_increase_alignment_p(void)213838fd1498Szrj symtab_node::can_increase_alignment_p (void)
213938fd1498Szrj {
214038fd1498Szrj   symtab_node *target = ultimate_alias_target ();
214138fd1498Szrj 
214238fd1498Szrj   /* For now support only variables.  */
214338fd1498Szrj   if (!VAR_P (decl))
214438fd1498Szrj     return false;
214538fd1498Szrj 
214638fd1498Szrj   /* With -fno-toplevel-reorder we may have already output the constant.  */
214738fd1498Szrj   if (TREE_ASM_WRITTEN (target->decl))
214838fd1498Szrj     return false;
214938fd1498Szrj 
215038fd1498Szrj   /* If target is already placed in an anchor, we can not touch its
215138fd1498Szrj      alignment.  */
215238fd1498Szrj   if (DECL_RTL_SET_P (target->decl)
215338fd1498Szrj       && MEM_P (DECL_RTL (target->decl))
215438fd1498Szrj       && SYMBOL_REF_HAS_BLOCK_INFO_P (XEXP (DECL_RTL (target->decl), 0)))
215538fd1498Szrj     return false;
215638fd1498Szrj 
215738fd1498Szrj   /* Constant pool entries may be shared.  */
215838fd1498Szrj   if (DECL_IN_CONSTANT_POOL (target->decl))
215938fd1498Szrj     return false;
216038fd1498Szrj 
216138fd1498Szrj   /* We cannot change alignment of symbols that may bind to symbols
216238fd1498Szrj      in other translation unit that may contain a definition with lower
216338fd1498Szrj      alignment.  */
216438fd1498Szrj   if (!decl_binds_to_current_def_p (decl))
216538fd1498Szrj     return false;
216638fd1498Szrj 
216738fd1498Szrj   /* When compiling partition, be sure the symbol is not output by other
216838fd1498Szrj      partition.  */
216938fd1498Szrj   if (flag_ltrans
217038fd1498Szrj       && (target->in_other_partition
217138fd1498Szrj 	  || target->get_partitioning_class () == SYMBOL_DUPLICATE))
217238fd1498Szrj     return false;
217338fd1498Szrj 
217438fd1498Szrj   /* Do not override the alignment as specified by the ABI when the used
217538fd1498Szrj      attribute is set.  */
217638fd1498Szrj   if (DECL_PRESERVE_P (decl) || DECL_PRESERVE_P (target->decl))
217738fd1498Szrj     return false;
217838fd1498Szrj 
217938fd1498Szrj   /* Do not override explicit alignment set by the user when an explicit
218038fd1498Szrj      section name is also used.  This is a common idiom used by many
218138fd1498Szrj      software projects.  */
218238fd1498Szrj   if (DECL_SECTION_NAME (target->decl) != NULL && !target->implicit_section)
218338fd1498Szrj     return false;
218438fd1498Szrj 
218538fd1498Szrj   return true;
218638fd1498Szrj }
218738fd1498Szrj 
218838fd1498Szrj /* Worker for symtab_node::increase_alignment.  */
218938fd1498Szrj 
219038fd1498Szrj static bool
increase_alignment_1(symtab_node * n,void * v)219138fd1498Szrj increase_alignment_1 (symtab_node *n, void *v)
219238fd1498Szrj {
219338fd1498Szrj   unsigned int align = (size_t)v;
219438fd1498Szrj   if (DECL_ALIGN (n->decl) < align
219538fd1498Szrj       && n->can_increase_alignment_p ())
219638fd1498Szrj     {
219738fd1498Szrj       SET_DECL_ALIGN (n->decl, align);
219838fd1498Szrj       DECL_USER_ALIGN (n->decl) = 1;
219938fd1498Szrj     }
220038fd1498Szrj   return false;
220138fd1498Szrj }
220238fd1498Szrj 
220338fd1498Szrj /* Increase alignment of THIS to ALIGN.  */
220438fd1498Szrj 
220538fd1498Szrj void
increase_alignment(unsigned int align)220638fd1498Szrj symtab_node::increase_alignment (unsigned int align)
220738fd1498Szrj {
220838fd1498Szrj   gcc_assert (can_increase_alignment_p () && align < MAX_OFILE_ALIGNMENT);
220938fd1498Szrj   ultimate_alias_target()->call_for_symbol_and_aliases (increase_alignment_1,
221038fd1498Szrj 						        (void *)(size_t) align,
221138fd1498Szrj 						        true);
221238fd1498Szrj   gcc_assert (DECL_ALIGN (decl) >= align);
221338fd1498Szrj }
221438fd1498Szrj 
221538fd1498Szrj /* Helper for symtab_node::definition_alignment.  */
221638fd1498Szrj 
221738fd1498Szrj static bool
get_alignment_1(symtab_node * n,void * v)221838fd1498Szrj get_alignment_1 (symtab_node *n, void *v)
221938fd1498Szrj {
222038fd1498Szrj   *((unsigned int *)v) = MAX (*((unsigned int *)v), DECL_ALIGN (n->decl));
222138fd1498Szrj   return false;
222238fd1498Szrj }
222338fd1498Szrj 
222438fd1498Szrj /* Return desired alignment of the definition.  This is NOT alignment useful
222538fd1498Szrj    to access THIS, because THIS may be interposable and DECL_ALIGN should
222638fd1498Szrj    be used instead.  It however must be guaranteed when output definition
222738fd1498Szrj    of THIS.  */
222838fd1498Szrj 
222938fd1498Szrj unsigned int
definition_alignment()223038fd1498Szrj symtab_node::definition_alignment ()
223138fd1498Szrj {
223238fd1498Szrj   unsigned int align = 0;
223338fd1498Szrj   gcc_assert (!alias);
223438fd1498Szrj   call_for_symbol_and_aliases (get_alignment_1, &align, true);
223538fd1498Szrj   return align;
223638fd1498Szrj }
223738fd1498Szrj 
223838fd1498Szrj /* Return symbol used to separate symbol name from suffix.  */
223938fd1498Szrj 
224038fd1498Szrj char
symbol_suffix_separator()224138fd1498Szrj symbol_table::symbol_suffix_separator ()
224238fd1498Szrj {
224338fd1498Szrj #ifndef NO_DOT_IN_LABEL
224438fd1498Szrj   return '.';
224538fd1498Szrj #elif !defined NO_DOLLAR_IN_LABEL
224638fd1498Szrj   return '$';
224738fd1498Szrj #else
224838fd1498Szrj   return '_';
224938fd1498Szrj #endif
225038fd1498Szrj }
225138fd1498Szrj 
225238fd1498Szrj /* Return true when references to this symbol from REF must bind to current
225338fd1498Szrj    definition in final executable.  */
225438fd1498Szrj 
225538fd1498Szrj bool
binds_to_current_def_p(symtab_node * ref)225638fd1498Szrj symtab_node::binds_to_current_def_p (symtab_node *ref)
225738fd1498Szrj {
225838fd1498Szrj   if (!definition)
225938fd1498Szrj     return false;
226038fd1498Szrj   if (transparent_alias)
226138fd1498Szrj     return definition
226238fd1498Szrj 	   && get_alias_target()->binds_to_current_def_p (ref);
2263*58e805e6Szrj   cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
2264*58e805e6Szrj   if (cnode && cnode->ifunc_resolver)
226538fd1498Szrj     return false;
226638fd1498Szrj   if (decl_binds_to_current_def_p (decl))
226738fd1498Szrj     return true;
226838fd1498Szrj 
226938fd1498Szrj   /* Inline clones always binds locally.  */
227038fd1498Szrj   if (cnode && cnode->global.inlined_to)
227138fd1498Szrj     return true;
227238fd1498Szrj 
227338fd1498Szrj   if (DECL_EXTERNAL (decl))
227438fd1498Szrj     return false;
227538fd1498Szrj 
227638fd1498Szrj   gcc_assert (externally_visible);
227738fd1498Szrj 
227838fd1498Szrj   if (ref)
227938fd1498Szrj     {
228038fd1498Szrj       cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
228138fd1498Szrj       if (cref)
228238fd1498Szrj 	ref = cref->global.inlined_to;
228338fd1498Szrj     }
228438fd1498Szrj 
228538fd1498Szrj   /* If this is a reference from symbol itself and there are no aliases, we
228638fd1498Szrj      may be sure that the symbol was not interposed by something else because
228738fd1498Szrj      the symbol itself would be unreachable otherwise.  This is important
228838fd1498Szrj      to optimize recursive functions well.
228938fd1498Szrj 
229038fd1498Szrj      This assumption may be broken by inlining: if symbol is interposable
229138fd1498Szrj      but the body is available (i.e. declared inline), inliner may make
229238fd1498Szrj      the body reachable even with interposition.  */
229338fd1498Szrj   if (this == ref && !has_aliases_p ()
229438fd1498Szrj       && (!cnode
229538fd1498Szrj 	  || symtab->state >= IPA_SSA_AFTER_INLINING
229638fd1498Szrj 	  || get_availability () >= AVAIL_INTERPOSABLE))
229738fd1498Szrj     return true;
229838fd1498Szrj 
229938fd1498Szrj 
230038fd1498Szrj   /* References within one comdat group are always bound in a group.  */
230138fd1498Szrj   if (ref
230238fd1498Szrj       && symtab->state >= IPA_SSA_AFTER_INLINING
230338fd1498Szrj       && get_comdat_group ()
230438fd1498Szrj       && get_comdat_group () == ref->get_comdat_group ())
230538fd1498Szrj     return true;
230638fd1498Szrj 
230738fd1498Szrj   return false;
230838fd1498Szrj }
230938fd1498Szrj 
231038fd1498Szrj /* Return true if symbol should be output to the symbol table.  */
231138fd1498Szrj 
231238fd1498Szrj bool
output_to_lto_symbol_table_p(void)231338fd1498Szrj symtab_node::output_to_lto_symbol_table_p (void)
231438fd1498Szrj {
231538fd1498Szrj   /* Only externally visible symbols matter.  */
231638fd1498Szrj   if (!TREE_PUBLIC (decl))
231738fd1498Szrj     return false;
231838fd1498Szrj   if (!real_symbol_p ())
231938fd1498Szrj     return false;
232038fd1498Szrj   /* FIXME: variables probably should not be considered as real symbols at
232138fd1498Szrj      first place.  */
232238fd1498Szrj   if (VAR_P (decl) && DECL_HARD_REGISTER (decl))
232338fd1498Szrj     return false;
232438fd1498Szrj   /* FIXME: Builtins corresponding to real functions probably should have
232538fd1498Szrj      symbol table entries.  */
232638fd1498Szrj   if (is_builtin_fn (decl))
232738fd1498Szrj     return false;
232838fd1498Szrj 
232938fd1498Szrj   /* We have real symbol that should be in symbol table.  However try to trim
233038fd1498Szrj      down the refernces to libraries bit more because linker will otherwise
233138fd1498Szrj      bring unnecesary object files into the final link.
233238fd1498Szrj      FIXME: The following checks can easily be confused i.e. by self recursive
233338fd1498Szrj      function or self-referring variable.  */
233438fd1498Szrj 
233538fd1498Szrj   /* We keep external functions in symtab for sake of inlining
233638fd1498Szrj      and devirtualization.  We do not want to see them in symbol table as
233738fd1498Szrj      references unless they are really used.  */
233838fd1498Szrj   cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
233938fd1498Szrj   if (cnode && (!definition || DECL_EXTERNAL (decl))
234038fd1498Szrj       && cnode->callers)
234138fd1498Szrj     return true;
234238fd1498Szrj 
234338fd1498Szrj  /* Ignore all references from external vars initializers - they are not really
234438fd1498Szrj     part of the compilation unit until they are used by folding.  Some symbols,
234538fd1498Szrj     like references to external construction vtables can not be referred to at
234638fd1498Szrj     all.  We decide this at can_refer_decl_in_current_unit_p.  */
234738fd1498Szrj  if (!definition || DECL_EXTERNAL (decl))
234838fd1498Szrj     {
234938fd1498Szrj       int i;
235038fd1498Szrj       struct ipa_ref *ref;
235138fd1498Szrj       for (i = 0; iterate_referring (i, ref); i++)
235238fd1498Szrj 	{
235338fd1498Szrj 	  if (ref->use == IPA_REF_ALIAS)
235438fd1498Szrj 	    continue;
235538fd1498Szrj           if (is_a <cgraph_node *> (ref->referring))
235638fd1498Szrj 	    return true;
235738fd1498Szrj 	  if (!DECL_EXTERNAL (ref->referring->decl))
235838fd1498Szrj 	    return true;
235938fd1498Szrj 	}
236038fd1498Szrj       return false;
236138fd1498Szrj     }
236238fd1498Szrj   return true;
236338fd1498Szrj }
2364