/* Symbol table.
   Copyright (C) 2012-2022 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "timevar.h"
#include "cgraph.h"
#include "lto-streamer.h"
#include "print-tree.h"
#include "varasm.h"
#include "langhooks.h"
#include "output.h"
#include "ipa-utils.h"
#include "calls.h"
#include "stringpool.h"
#include "attribs.h"
#include "builtins.h"
#include "fold-const.h"

static const char *ipa_ref_use_name[] = {"read","write","addr","alias"};

const char * const ld_plugin_symbol_resolution_names[]=
{
  "",
  "undef",
  "prevailing_def",
  "prevailing_def_ironly",
  "preempted_reg",
  "preempted_ir",
  "resolved_ir",
  "resolved_exec",
  "resolved_dyn",
  "prevailing_def_ironly_exp"
};

/* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at ALIAS
   until we find an identifier that is not itself a transparent alias.  */

static inline tree
ultimate_transparent_alias_target (tree alias)
{
  tree target = alias;

  while (IDENTIFIER_TRANSPARENT_ALIAS (target))
    {
      gcc_checking_assert (TREE_CHAIN (target));
      target = TREE_CHAIN (target);
    }
  gcc_checking_assert (! IDENTIFIER_TRANSPARENT_ALIAS (target)
		       && ! TREE_CHAIN (target));

  return target;
}


/* Hash asmnames ignoring the user specified marks.  */

hashval_t
symbol_table::decl_assembler_name_hash (const_tree asmname)
{
  if (IDENTIFIER_POINTER (asmname)[0] == '*')
    {
      const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
      size_t ulp_len = strlen (user_label_prefix);

      if (ulp_len == 0)
	;
      else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
	decl_str += ulp_len;

      return htab_hash_string (decl_str);
    }

  return htab_hash_string (IDENTIFIER_POINTER (asmname));
}

/* Return true if assembler names NAME1 and NAME2 leads to the same symbol
   name.  */

bool
symbol_table::assembler_names_equal_p (const char *name1, const char *name2)
{
  if (name1 != name2)
    {
      if (name1[0] == '*')
	{
	  size_t ulp_len = strlen (user_label_prefix);

	  name1 ++;

	  if (ulp_len == 0)
	    ;
	  else if (strncmp (name1, user_label_prefix, ulp_len) == 0)
	    name1 += ulp_len;
	  else
	    return false;
	}
      if (name2[0] == '*')
	{
	  size_t ulp_len = strlen (user_label_prefix);

	  name2 ++;

	  if (ulp_len == 0)
	    ;
	  else if (strncmp (name2, user_label_prefix, ulp_len) == 0)
	    name2 += ulp_len;
	  else
	    return false;
	}
      return !strcmp (name1, name2);
    }
  return true;
}

/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */

bool
symbol_table::decl_assembler_name_equal (tree decl, const_tree asmname)
{
  tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
  const char *decl_str;
  const char *asmname_str;

  if (decl_asmname == asmname)
    return true;

  decl_str = IDENTIFIER_POINTER (decl_asmname);
  asmname_str = IDENTIFIER_POINTER (asmname);
  return assembler_names_equal_p (decl_str, asmname_str);
}


/* Returns nonzero if P1 and P2 are equal.  */

/* Insert NODE to assembler name hash.  */

void
symbol_table::insert_to_assembler_name_hash (symtab_node *node,
					     bool with_clones)
{
  if (is_a <varpool_node *> (node) && DECL_HARD_REGISTER (node->decl))
    return;
  gcc_checking_assert (!node->previous_sharing_asm_name
		       && !node->next_sharing_asm_name);
  if (assembler_name_hash)
    {
      symtab_node **aslot;
      cgraph_node *cnode;
      tree decl = node->decl;

      tree name = DECL_ASSEMBLER_NAME (node->decl);

      /* C++ FE can produce decls without associated assembler name and insert
	 them to symtab to hold section or TLS information.  */
      if (!name)
	return;

      hashval_t hash = decl_assembler_name_hash (name);
      aslot = assembler_name_hash->find_slot_with_hash (name, hash, INSERT);
      gcc_assert (*aslot != node);
      node->next_sharing_asm_name = (symtab_node *)*aslot;
      if (*aslot != NULL)
	(*aslot)->previous_sharing_asm_name = node;
      *aslot = node;

      /* Update also possible inline clones sharing a decl.  */
      cnode = dyn_cast <cgraph_node *> (node);
      if (cnode && cnode->clones && with_clones)
	for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
	  if (cnode->decl == decl)
	    insert_to_assembler_name_hash (cnode, true);
    }

}

/* Remove NODE from assembler name hash.  */

void
symbol_table::unlink_from_assembler_name_hash (symtab_node *node,
					       bool with_clones)
{
  if (assembler_name_hash)
    {
      cgraph_node *cnode;
      tree decl = node->decl;

      if (node->next_sharing_asm_name)
	node->next_sharing_asm_name->previous_sharing_asm_name
	  = node->previous_sharing_asm_name;
      if (node->previous_sharing_asm_name)
	{
	  node->previous_sharing_asm_name->next_sharing_asm_name
	    = node->next_sharing_asm_name;
	}
      else
	{
	  tree name = DECL_ASSEMBLER_NAME (node->decl);
          symtab_node **slot;

	  if (!name)
	    return;

	  hashval_t hash = decl_assembler_name_hash (name);
	  slot = assembler_name_hash->find_slot_with_hash (name, hash,
							   NO_INSERT);
	  gcc_assert (*slot == node);
	  if (!node->next_sharing_asm_name)
	    assembler_name_hash->clear_slot (slot);
	  else
	    *slot = node->next_sharing_asm_name;
	}
      node->next_sharing_asm_name = NULL;
      node->previous_sharing_asm_name = NULL;

      /* Update also possible inline clones sharing a decl.  */
      cnode = dyn_cast <cgraph_node *> (node);
      if (cnode && cnode->clones && with_clones)
	for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
	  if (cnode->decl == decl)
	    unlink_from_assembler_name_hash (cnode, true);
    }
}

/* Arrange node to be first in its entry of assembler_name_hash.  */

void
symbol_table::symtab_prevail_in_asm_name_hash (symtab_node *node)
{
  unlink_from_assembler_name_hash (node, false);
  insert_to_assembler_name_hash (node, false);
}

/* Initialize asm name hash unless.  */

void
symbol_table::symtab_initialize_asm_name_hash (void)
{
  symtab_node *node;
  if (!assembler_name_hash)
    {
      assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
      FOR_EACH_SYMBOL (node)
	insert_to_assembler_name_hash (node, false);
    }
}

/* Set the DECL_ASSEMBLER_NAME and update symtab hashtables.  */

void
symbol_table::change_decl_assembler_name (tree decl, tree name)
{
  symtab_node *node = NULL;

  /* We can have user ASM names on things, like global register variables, that
     are not in the symbol table.  */
  if ((VAR_P (decl) && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
      || TREE_CODE (decl) == FUNCTION_DECL)
    node = symtab_node::get (decl);
  if (!DECL_ASSEMBLER_NAME_SET_P (decl))
    {
      SET_DECL_ASSEMBLER_NAME (decl, name);
      if (node)
	insert_to_assembler_name_hash (node, true);
    }
  else
    {
      if (name == DECL_ASSEMBLER_NAME (decl))
	return;

      tree alias = (IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl))
		    ? TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
		    : NULL);
      if (node)
	unlink_from_assembler_name_hash (node, true);

      const char *old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
      if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
	  && DECL_RTL_SET_P (decl))
	warning (0, "%qD renamed after being referenced in assembly", decl);

      SET_DECL_ASSEMBLER_NAME (decl, name);
      if (alias)
	{
	  IDENTIFIER_TRANSPARENT_ALIAS (name) = 1;
	  TREE_CHAIN (name) = alias;
	}
      /* If we change assembler name, also all transparent aliases must
	 be updated.  There are three kinds - those having same assembler name,
	 those being renamed in varasm.cc and weakref being renamed by the
	 assembler.  */
      if (node)
	{
	  insert_to_assembler_name_hash (node, true);
	  ipa_ref *ref;
	  for (unsigned i = 0; node->iterate_direct_aliases (i, ref); i++)
	    {
	      struct symtab_node *alias = ref->referring;
	      if (alias->transparent_alias && !alias->weakref
		  && symbol_table::assembler_names_equal_p
			 (old_name, IDENTIFIER_POINTER (
				      DECL_ASSEMBLER_NAME (alias->decl))))
		change_decl_assembler_name (alias->decl, name);
	      else if (alias->transparent_alias
		       && IDENTIFIER_TRANSPARENT_ALIAS (alias->decl))
		{
		  gcc_assert (TREE_CHAIN (DECL_ASSEMBLER_NAME (alias->decl))
			      && IDENTIFIER_TRANSPARENT_ALIAS
				     (DECL_ASSEMBLER_NAME (alias->decl)));

		  TREE_CHAIN (DECL_ASSEMBLER_NAME (alias->decl)) = 
		    ultimate_transparent_alias_target
			 (DECL_ASSEMBLER_NAME (node->decl));
		}
#ifdef ASM_OUTPUT_WEAKREF
	     else gcc_assert (!alias->transparent_alias || alias->weakref);
#else
	     else gcc_assert (!alias->transparent_alias);
#endif
	    }
	  gcc_assert (!node->transparent_alias || !node->definition
		      || node->weakref
		      || TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
		      || symbol_table::assembler_names_equal_p
			  (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
			   IDENTIFIER_POINTER
			     (DECL_ASSEMBLER_NAME
				 (node->get_alias_target ()->decl))));
	}
    }
}

/* Hash sections by their names.  */

hashval_t
section_name_hasher::hash (section_hash_entry *n)
{
  return htab_hash_string (n->name);
}

/* Return true if section P1 name equals to P2.  */

bool
section_name_hasher::equal (section_hash_entry *n1, const char *name)
{
  return n1->name == name || !strcmp (n1->name, name);
}

/* Bump the reference count on ENTRY so that it is retained.  */

static section_hash_entry *
retain_section_hash_entry (section_hash_entry *entry)
{
  entry->ref_count++;
  return entry;
}

/* Drop the reference count on ENTRY and remove it if the reference
   count drops to zero.  */

static void
release_section_hash_entry (section_hash_entry *entry)
{
  if (entry)
    {
      entry->ref_count--;
      if (!entry->ref_count)
	{
	  hashval_t hash = htab_hash_string (entry->name);
	  section_hash_entry **slot
	    = symtab->section_hash->find_slot_with_hash (entry->name,
						 hash, INSERT);
	  ggc_free (entry);
	  symtab->section_hash->clear_slot (slot);
	}
    }
}

/* Add node into symbol table.  This function is not used directly, but via
   cgraph/varpool node creation routines.  */

void
symtab_node::register_symbol (void)
{
  symtab->register_symbol (this);

  if (!decl->decl_with_vis.symtab_node)
    decl->decl_with_vis.symtab_node = this;

  ref_list.clear ();

  /* Be sure to do this last; C++ FE might create new nodes via
     DECL_ASSEMBLER_NAME langhook!  */
  symtab->insert_to_assembler_name_hash (this, false);
}

/* Remove NODE from same comdat group.   */

void
symtab_node::remove_from_same_comdat_group (void)
{
  if (same_comdat_group)
    {
      symtab_node *prev;
      for (prev = same_comdat_group;
	   prev->same_comdat_group != this;
	   prev = prev->same_comdat_group)
	;
      if (same_comdat_group == prev)
	prev->same_comdat_group = NULL;
      else
	prev->same_comdat_group = same_comdat_group;
      same_comdat_group = NULL;
      set_comdat_group (NULL);
    }
}

/* Remove node from symbol table.  This function is not used directly, but via
   cgraph/varpool node removal routines.
   INFO is a clone info to attach to new root of clone tree (if any).  */

void
symtab_node::unregister (clone_info *info)
{
  remove_all_references ();
  remove_all_referring ();

  /* Remove reference to section.  */
  set_section_for_node (NULL);

  remove_from_same_comdat_group ();

  symtab->unregister (this);

  /* During LTO symtab merging we temporarily corrupt decl to symtab node
     hash.  */
  gcc_assert (decl->decl_with_vis.symtab_node || in_lto_p);
  if (decl->decl_with_vis.symtab_node == this)
    {
      symtab_node *replacement_node = NULL;
      if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
	replacement_node = cnode->find_replacement (info);
      decl->decl_with_vis.symtab_node = replacement_node;
    }
  if (!is_a <varpool_node *> (this) || !DECL_HARD_REGISTER (decl))
    symtab->unlink_from_assembler_name_hash (this, false);
  if (in_init_priority_hash)
    symtab->init_priority_hash->remove (this);
}


/* Remove symbol from symbol table.  */

void
symtab_node::remove (void)
{
  if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
    cnode->remove ();
  else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
    vnode->remove ();
}

/* Add NEW_ to the same comdat group that OLD is in.  */

void
symtab_node::add_to_same_comdat_group (symtab_node *old_node)
{
  gcc_assert (old_node->get_comdat_group ());
  gcc_assert (!same_comdat_group);
  gcc_assert (this != old_node);

  set_comdat_group (old_node->get_comdat_group ());
  same_comdat_group = old_node;
  if (!old_node->same_comdat_group)
    old_node->same_comdat_group = this;
  else
    {
      symtab_node *n;
      for (n = old_node->same_comdat_group;
	   n->same_comdat_group != old_node;
	   n = n->same_comdat_group)
	;
      n->same_comdat_group = this;
    }

  cgraph_node *n;
  if (comdat_local_p ()
      && (n = dyn_cast <cgraph_node *> (this)) != NULL)
    {
      for (cgraph_edge *e = n->callers; e; e = e->next_caller)
	if (e->caller->inlined_to)
	  e->caller->inlined_to->calls_comdat_local = true;
	else
	  e->caller->calls_comdat_local = true;
    }
}

/* Dissolve the same_comdat_group list in which NODE resides.  */

void
symtab_node::dissolve_same_comdat_group_list (void)
{
  symtab_node *n = this;
  symtab_node *next;

  if (!same_comdat_group)
    return;
  do
    {
      next = n->same_comdat_group;
      n->same_comdat_group = NULL;
      if (dyn_cast <cgraph_node *> (n))
	dyn_cast <cgraph_node *> (n)->calls_comdat_local = false;
      /* Clear comdat_group for comdat locals, since
         make_decl_local doesn't.  */
      if (!TREE_PUBLIC (n->decl))
	n->set_comdat_group (NULL);
      n = next;
    }
  while (n != this);
}

/* Return printable assembler name of NODE.
   This function is used only for debugging.  When assembler name
   is unknown go with identifier name.  */

const char *
symtab_node::asm_name () const
{
  if (!DECL_ASSEMBLER_NAME_SET_P (decl))
    return name ();
  return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
}

/* Return printable identifier name.  */

const char *
symtab_node::name () const
{
  if (!DECL_NAME (decl))
    {
      if (DECL_ASSEMBLER_NAME_SET_P (decl))
	return asm_name ();
      else
        return "<unnamed>";
    }
  return lang_hooks.decl_printable_name (decl, 2);
}

const char *
symtab_node::get_dump_name (bool asm_name_p) const
{
#define EXTRA 16
  const char *fname = asm_name_p ? asm_name () : name ();
  unsigned l = strlen (fname);

  char *s = (char *)ggc_internal_cleared_alloc (l + EXTRA);
  snprintf (s, l + EXTRA, "%s/%d", fname, order);

  return s;
}

const char *
symtab_node::dump_name () const
{
  return get_dump_name (false);
}

const char *
symtab_node::dump_asm_name () const
{
  return get_dump_name (true);
}

/* Return ipa reference from this symtab_node to
   REFERRED_NODE or REFERRED_VARPOOL_NODE. USE_TYPE specify type
   of the use.  */

ipa_ref *
symtab_node::create_reference (symtab_node *referred_node,
			       enum ipa_ref_use use_type)
{
  return create_reference (referred_node, use_type, NULL);
}


/* Return ipa reference from this symtab_node to
   REFERRED_NODE or REFERRED_VARPOOL_NODE. USE_TYPE specify type
   of the use and STMT the statement (if it exists).  */

ipa_ref *
symtab_node::create_reference (symtab_node *referred_node,
			       enum ipa_ref_use use_type, gimple *stmt)
{
  ipa_ref *ref = NULL, *ref2 = NULL;
  ipa_ref_list *list, *list2;
  ipa_ref_t *old_references;

  gcc_checking_assert (!stmt || is_a <cgraph_node *> (this));
  gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);

  list = &ref_list;
  old_references = list->references.address ();
  list->references.safe_grow (list->references.length () + 1, false);
  ref = &list->references.last ();

  list2 = &referred_node->ref_list;

  /* IPA_REF_ALIAS is always inserted at the beginning of the list.   */
  if(use_type == IPA_REF_ALIAS)
    {
      list2->referring.safe_insert (0, ref);
      ref->referred_index = 0;

      for (unsigned int i = 1; i < list2->referring.length (); i++)
	list2->referring[i]->referred_index = i;
    }
  else
    {
      list2->referring.safe_push (ref);
      ref->referred_index = list2->referring.length () - 1;
    }

  ref->referring = this;
  ref->referred = referred_node;
  ref->stmt = stmt;
  ref->lto_stmt_uid = 0;
  ref->speculative_id = 0;
  ref->use = use_type;
  ref->speculative = 0;

  /* If vector was moved in memory, update pointers.  */
  if (old_references != list->references.address ())
    {
      int i;
      for (i = 0; iterate_reference(i, ref2); i++)
	ref2->referred_ref_list ()->referring[ref2->referred_index] = ref2;
    }
  return ref;
}

ipa_ref *
symtab_node::maybe_create_reference (tree val, gimple *stmt)
{
  STRIP_NOPS (val);
  ipa_ref_use use_type;

  switch (TREE_CODE (val))
    {
    case VAR_DECL:
      use_type = IPA_REF_LOAD;
      break;
    case ADDR_EXPR:
      use_type = IPA_REF_ADDR;
      break;
    default:
      gcc_assert (!handled_component_p (val));
      return NULL;
    }

  val = get_base_var (val);
  if (val && VAR_OR_FUNCTION_DECL_P (val))
    {
      symtab_node *referred = symtab_node::get (val);
      gcc_checking_assert (referred);
      return create_reference (referred, use_type, stmt);
    }
  return NULL;
}

/* Clone all references from symtab NODE to this symtab_node.  */

void
symtab_node::clone_references (symtab_node *node)
{
  ipa_ref *ref = NULL, *ref2 = NULL;
  int i;
  for (i = 0; node->iterate_reference (i, ref); i++)
    {
      bool speculative = ref->speculative;
      unsigned int stmt_uid = ref->lto_stmt_uid;
      unsigned int spec_id = ref->speculative_id;

      ref2 = create_reference (ref->referred, ref->use, ref->stmt);
      ref2->speculative = speculative;
      ref2->lto_stmt_uid = stmt_uid;
      ref2->speculative_id = spec_id;
    }
}

/* Clone all referring from symtab NODE to this symtab_node.  */

void
symtab_node::clone_referring (symtab_node *node)
{
  ipa_ref *ref = NULL, *ref2 = NULL;
  int i;
  for (i = 0; node->iterate_referring(i, ref); i++)
    {
      bool speculative = ref->speculative;
      unsigned int stmt_uid = ref->lto_stmt_uid;
      unsigned int spec_id = ref->speculative_id;

      ref2 = ref->referring->create_reference (this, ref->use, ref->stmt);
      ref2->speculative = speculative;
      ref2->lto_stmt_uid = stmt_uid;
      ref2->speculative_id = spec_id;
    }
}

/* Clone reference REF to this symtab_node and set its stmt to STMT.  */

ipa_ref *
symtab_node::clone_reference (ipa_ref *ref, gimple *stmt)
{
  bool speculative = ref->speculative;
  unsigned int stmt_uid = ref->lto_stmt_uid;
  unsigned int spec_id = ref->speculative_id;
  ipa_ref *ref2;

  ref2 = create_reference (ref->referred, ref->use, stmt);
  ref2->speculative = speculative;
  ref2->lto_stmt_uid = stmt_uid;
  ref2->speculative_id = spec_id;
  return ref2;
}

/* Find the structure describing a reference to REFERRED_NODE
   and associated with statement STMT.  */

ipa_ref *
symtab_node::find_reference (symtab_node *referred_node,
			     gimple *stmt, unsigned int lto_stmt_uid)
{
  ipa_ref *r = NULL;
  int i;

  for (i = 0; iterate_reference (i, r); i++)
    if (r->referred == referred_node
	&& !r->speculative
	&& ((stmt && r->stmt == stmt)
	    || (lto_stmt_uid && r->lto_stmt_uid == lto_stmt_uid)
	    || (!stmt && !lto_stmt_uid && !r->stmt && !r->lto_stmt_uid)))
      return r;
  return NULL;
}

/* Remove all references that are associated with statement STMT.  */

void
symtab_node::remove_stmt_references (gimple *stmt)
{
  ipa_ref *r = NULL;
  int i = 0;

  while (iterate_reference (i, r))
    if (r->stmt == stmt)
      r->remove_reference ();
    else
      i++;
}

/* Remove all stmt references in non-speculative references in THIS
   and all clones.
   Those are not maintained during inlining & cloning.
   The exception are speculative references that are updated along
   with callgraph edges associated with them.  */

void
symtab_node::clear_stmts_in_references (void)
{
  ipa_ref *r = NULL;
  int i;

  for (i = 0; iterate_reference (i, r); i++)
    if (!r->speculative)
      {
	r->stmt = NULL;
	r->lto_stmt_uid = 0;
	r->speculative_id = 0;
      }
  cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
  if (cnode)
    {
      if (cnode->clones)
	for (cnode = cnode->clones; cnode; cnode = cnode->next_sibling_clone)
	  cnode->clear_stmts_in_references ();
    }
}

/* Remove all references in ref list.  */

void
symtab_node::remove_all_references (void)
{
  while (ref_list.references.length ())
    ref_list.references.last ().remove_reference ();
  ref_list.references.release ();
}

/* Remove all referring items in ref list.  */

void
symtab_node::remove_all_referring (void)
{
  while (ref_list.referring.length ())
    ref_list.referring.last ()->remove_reference ();
  ref_list.referring.release ();
}

/* Dump references in ref list to FILE.  */

void
symtab_node::dump_references (FILE *file)
{
  ipa_ref *ref = NULL;
  int i;
  for (i = 0; iterate_reference (i, ref); i++)
    {
      fprintf (file, "%s (%s) ", ref->referred->dump_asm_name (),
	       ipa_ref_use_name[ref->use]);
      if (ref->speculative)
	fprintf (file, "(speculative) ");
    }
  fprintf (file, "\n");
}

/* Dump referring in list to FILE.  */

void
symtab_node::dump_referring (FILE *file)
{
  ipa_ref *ref = NULL;
  int i;
  for (i = 0; iterate_referring(i, ref); i++)
    {
      fprintf (file, "%s (%s) ", ref->referring->dump_asm_name (),
	       ipa_ref_use_name[ref->use]);
      if (ref->speculative)
	fprintf (file, "(speculative) ");
    }
  fprintf (file, "\n");
}

static const char * const symtab_type_names[] = {"symbol", "function", "variable"};

/* Dump the visibility of the symbol.  */

const char *
symtab_node::get_visibility_string () const
{
  static const char * const visibility_types[]
    = { "default", "protected", "hidden", "internal" };
  return visibility_types[DECL_VISIBILITY (decl)];
}

/* Dump the type_name of the symbol.  */
const char *
symtab_node::get_symtab_type_string () const
{
  return symtab_type_names[type];
}

/* Dump base fields of symtab nodes to F.  Not to be used directly.  */

void
symtab_node::dump_base (FILE *f)
{
  static const char * const visibility_types[] = {
    "default", "protected", "hidden", "internal"
  };

  fprintf (f, "%s (%s)", dump_asm_name (), name ());
  if (dump_flags & TDF_ADDRESS)
    dump_addr (f, " @", (void *)this);
  fprintf (f, "\n  Type: %s", symtab_type_names[type]);

  if (definition)
    fprintf (f, " definition");
  if (analyzed)
    fprintf (f, " analyzed");
  if (alias)
    fprintf (f, " alias");
  if (transparent_alias)
    fprintf (f, " transparent_alias");
  if (weakref)
    fprintf (f, " weakref");
  if (symver)
    fprintf (f, " symver");
  if (cpp_implicit_alias)
    fprintf (f, " cpp_implicit_alias");
  if (alias_target)
    fprintf (f, " target:%s",
	     DECL_P (alias_target)
	     ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
				     (alias_target))
	     : IDENTIFIER_POINTER (alias_target));
  if (body_removed)
    fprintf (f, "\n  Body removed by symtab_remove_unreachable_nodes");
  fprintf (f, "\n  Visibility:");
  if (in_other_partition)
    fprintf (f, " in_other_partition");
  if (used_from_other_partition)
    fprintf (f, " used_from_other_partition");
  if (force_output)
    fprintf (f, " force_output");
  if (forced_by_abi)
    fprintf (f, " forced_by_abi");
  if (externally_visible)
    fprintf (f, " externally_visible");
  if (semantic_interposition)
    fprintf (f, " semantic_interposition");
  if (no_reorder)
    fprintf (f, " no_reorder");
  if (resolution != LDPR_UNKNOWN)
    fprintf (f, " %s",
 	     ld_plugin_symbol_resolution_names[(int)resolution]);
  if (TREE_ASM_WRITTEN (decl))
    fprintf (f, " asm_written");
  if (DECL_EXTERNAL (decl))
    fprintf (f, " external");
  if (TREE_PUBLIC (decl))
    fprintf (f, " public");
  if (DECL_COMMON (decl))
    fprintf (f, " common");
  if (DECL_WEAK (decl))
    fprintf (f, " weak");
  if (DECL_DLLIMPORT_P (decl))
    fprintf (f, " dll_import");
  if (DECL_COMDAT (decl))
    fprintf (f, " comdat");
  if (get_comdat_group ())
    fprintf (f, " comdat_group:%s",
	     IDENTIFIER_POINTER (get_comdat_group_id ()));
  if (DECL_ONE_ONLY (decl))
    fprintf (f, " one_only");
  if (get_section ())
    fprintf (f, " section:%s",
	     get_section ());
  if (implicit_section)
    fprintf (f," (implicit_section)");
  if (DECL_VISIBILITY_SPECIFIED (decl))
    fprintf (f, " visibility_specified");
  if (DECL_VISIBILITY (decl))
    fprintf (f, " visibility:%s",
	     visibility_types [DECL_VISIBILITY (decl)]);
  if (DECL_VIRTUAL_P (decl))
    fprintf (f, " virtual");
  if (DECL_ARTIFICIAL (decl))
    fprintf (f, " artificial");
  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      if (DECL_STATIC_CONSTRUCTOR (decl))
	fprintf (f, " constructor");
      if (DECL_STATIC_DESTRUCTOR (decl))
	fprintf (f, " destructor");
    }
  if (ifunc_resolver)
    fprintf (f, " ifunc_resolver");
  fprintf (f, "\n");

  if (same_comdat_group)
    fprintf (f, "  Same comdat group as: %s\n",
	     same_comdat_group->dump_asm_name ());
  if (next_sharing_asm_name)
    fprintf (f, "  next sharing asm name: %i\n",
	     next_sharing_asm_name->order);
  if (previous_sharing_asm_name)
    fprintf (f, "  previous sharing asm name: %i\n",
	     previous_sharing_asm_name->order);

  if (address_taken)
    fprintf (f, "  Address is taken.\n");
  if (aux)
    {
      fprintf (f, "  Aux:");
      dump_addr (f, " @", (void *)aux);
      fprintf (f, "\n");
    }

  fprintf (f, "  References: ");
  dump_references (f);
  fprintf (f, "  Referring: ");
  dump_referring (f);
  if (lto_file_data)
    fprintf (f, "  Read from file: %s\n",
	     lto_file_data->file_name);
}

/* Dump symtab node to F.  */

void
symtab_node::dump (FILE *f)
{
  if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
    cnode->dump (f);
  else if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
    vnode->dump (f);
}

void
symtab_node::dump_graphviz (FILE *f)
{
  if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
    cnode->dump_graphviz (f);
}

void
symbol_table::dump (FILE *f)
{
  symtab_node *node;
  fprintf (f, "Symbol table:\n\n");
  FOR_EACH_SYMBOL (node)
    node->dump (f);
}

void
symbol_table::dump_graphviz (FILE *f)
{
  symtab_node *node;
  fprintf (f, "digraph symtab {\n");
  FOR_EACH_SYMBOL (node)
    node->dump_graphviz (f);
  fprintf (f, "}\n");
}

DEBUG_FUNCTION void
symbol_table::debug (void)
{
  dump (stderr);
}

/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
   Return NULL if there's no such node.  */

symtab_node *
symtab_node::get_for_asmname (const_tree asmname)
{
  symtab_node *node;

  symtab->symtab_initialize_asm_name_hash ();
  hashval_t hash = symtab->decl_assembler_name_hash (asmname);
  symtab_node **slot
    = symtab->assembler_name_hash->find_slot_with_hash (asmname, hash,
							NO_INSERT);

  if (slot)
    {
      node = *slot;
      return node;
    }
  return NULL;
}

/* Dump symtab node NODE to stderr.  */

DEBUG_FUNCTION void
symtab_node::debug (void)
{
  dump (stderr);
}

/* Verify common part of symtab nodes.  */

#if __GNUC__ >= 10
/* Disable warnings about missing quoting in GCC diagnostics for
   the verification errors.  Their format strings don't follow GCC
   diagnostic conventions and the calls are ultimately followed by
   one to internal_error.  */
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wformat-diag"
#endif

DEBUG_FUNCTION bool
symtab_node::verify_base (void)
{
  bool error_found = false;
  symtab_node *hashed_node;

  if (is_a <cgraph_node *> (this))
    {
      if (TREE_CODE (decl) != FUNCTION_DECL)
	{
          error ("function symbol is not function");
          error_found = true;
	}
      else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
		!= NULL)
	       != dyn_cast <cgraph_node *> (this)->ifunc_resolver)
	{
	  error ("inconsistent %<ifunc%> attribute");
          error_found = true;
	}
    }
  else if (is_a <varpool_node *> (this))
    {
      if (!VAR_P (decl))
	{
          error ("variable symbol is not variable");
          error_found = true;
	}
    }
  else
    {
      error ("node has unknown type");
      error_found = true;
    }
  if (order < 0 || order >= symtab->order)
    {
      error ("node has invalid order %i", order);
      error_found = true;
    }
   
  if (symtab->state != LTO_STREAMING)
    {
      hashed_node = symtab_node::get (decl);
      if (!hashed_node)
	{
	  error ("node not found node->decl->decl_with_vis.symtab_node");
	  error_found = true;
	}
      if (hashed_node != this
	  && (!is_a <cgraph_node *> (this)
	      || !dyn_cast <cgraph_node *> (this)->clone_of
	      || dyn_cast <cgraph_node *> (this)->clone_of->decl != decl))
	{
	  error ("node differs from node->decl->decl_with_vis.symtab_node");
	  error_found = true;
	}
    }
  if (symtab->assembler_name_hash)
    {
      hashed_node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (decl));
      if (hashed_node)
	{
	  if (hashed_node->previous_sharing_asm_name)
	    {
	      error ("assembler name hash list corrupted");
	      error_found = true;
	    }
	  else if (previous_sharing_asm_name == NULL)
	    {
	      if (hashed_node != this)
		{
		  error ("assembler name hash list corrupted");
		  error_found = true;
		}
	    }
	  else if (!(is_a <varpool_node *> (this) && DECL_HARD_REGISTER (decl)))
	    {
	      if (!asmname_hasher::equal (previous_sharing_asm_name,
					  DECL_ASSEMBLER_NAME (decl)))
		{
		  error ("node not found in symtab assembler name hash");
		  error_found = true;
		}
	    }
	}
    }
  if (previous_sharing_asm_name
      && previous_sharing_asm_name->next_sharing_asm_name != this)
    {
      error ("double linked list of assembler names corrupted");
      error_found = true;
    }
  if (body_removed && definition)
    {
      error ("node has body_removed but is definition");
      error_found = true;
    }
  if (analyzed && !definition)
    {
      error ("node is analyzed but it is not a definition");
      error_found = true;
    }
  if (cpp_implicit_alias && !alias)
    {
      error ("node is alias but not implicit alias");
      error_found = true;
    }
  if (alias && !definition && !weakref)
    {
      error ("node is alias but not definition");
      error_found = true;
    }
  if (weakref && !transparent_alias)
    {
      error ("node is weakref but not an transparent_alias");
      error_found = true;
    }
  if (transparent_alias && !alias)
    {
      error ("node is transparent_alias but not an alias");
      error_found = true;
    }
  if (symver && !alias)
    {
      error ("node is symver but not alias");
      error_found = true;
    }
  /* Limitation of gas requires us to output targets of symver aliases as
     global symbols.  This is binutils PR 25295.  */
  if (symver
      && (!TREE_PUBLIC (get_alias_target ()->decl)
	  || DECL_VISIBILITY (get_alias_target ()->decl) != VISIBILITY_DEFAULT))
    {
      error ("symver target is not exported with default visibility");
      error_found = true;
    }
  if (symver
      && (!TREE_PUBLIC (decl)
	  || DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT))
    {
      error ("symver is not exported with default visibility");
      error_found = true;
    }
  if (same_comdat_group)
    {
      symtab_node *n = same_comdat_group;

      if (!n->get_comdat_group ())
	{
	  error ("node is in same_comdat_group list but has no comdat_group");
	  error_found = true;
	}
      if (n->get_comdat_group () != get_comdat_group ())
	{
	  error ("same_comdat_group list across different groups");
	  error_found = true;
	}
      if (n->type != type)
	{
	  error ("mixing different types of symbol in same comdat groups is not supported");
	  error_found = true;
	}
      if (n == this)
	{
	  error ("node is alone in a comdat group");
	  error_found = true;
	}
      do
	{
	  if (!n->same_comdat_group)
	    {
	      error ("same_comdat_group is not a circular list");
	      error_found = true;
	      break;
	    }
	  n = n->same_comdat_group;
	}
      while (n != this);
      if (comdat_local_p ())
	{
	  ipa_ref *ref = NULL;

	  for (int i = 0; iterate_referring (i, ref); ++i)
	    {
	      if (!in_same_comdat_group_p (ref->referring))
		{
		  error ("comdat-local symbol referred to by %s outside its "
			 "comdat",
			 identifier_to_locale (ref->referring->name()));
		  error_found = true;
		}
	    }
	}
    }
  if (implicit_section && !get_section ())
    {
      error ("implicit_section flag is set but section isn%'t");
      error_found = true;
    }
  if (get_section () && get_comdat_group ()
      && !implicit_section
      && !lookup_attribute ("section", DECL_ATTRIBUTES (decl)))
    {
      error ("Both section and comdat group is set");
      error_found = true;
    }
  /* TODO: Add string table for sections, so we do not keep holding duplicated
     strings.  */
  if (alias && definition
      && get_section () != get_alias_target ()->get_section ()
      && (!get_section()
	  || !get_alias_target ()->get_section ()
	  || strcmp (get_section(),
		     get_alias_target ()->get_section ())))
    {
      error ("Alias and target%'s section differs");
      get_alias_target ()->dump (stderr);
      error_found = true;
    }
  if (alias && definition
      && get_comdat_group () != get_alias_target ()->get_comdat_group ())
    {
      error ("Alias and target%'s comdat groups differs");
      get_alias_target ()->dump (stderr);
      error_found = true;
    }
  if (transparent_alias && definition && !weakref)
    {
      symtab_node *to = get_alias_target ();
      const char *name1
	= IDENTIFIER_POINTER (
	    ultimate_transparent_alias_target (DECL_ASSEMBLER_NAME (decl)));
      const char *name2
	= IDENTIFIER_POINTER (
	    ultimate_transparent_alias_target (DECL_ASSEMBLER_NAME (to->decl)));
      if (!symbol_table::assembler_names_equal_p (name1, name2))
	{
	  error ("Transparent alias and target%'s assembler names differs");
	  get_alias_target ()->dump (stderr);
	  error_found = true;
	}
    }
  if (transparent_alias && definition
      && get_alias_target()->transparent_alias && get_alias_target()->analyzed)
    {
      error ("Chained transparent aliases");
      get_alias_target ()->dump (stderr);
      error_found = true;
    }

  return error_found;
}

/* Verify consistency of NODE.  */

DEBUG_FUNCTION void
symtab_node::verify (void)
{
  if (seen_error ())
    return;

  timevar_push (TV_CGRAPH_VERIFY);
  if (cgraph_node *node = dyn_cast <cgraph_node *> (this))
    node->verify_node ();
  else
    if (verify_base ())
      {
	debug ();
	internal_error ("symtab_node::verify failed");
      }
  timevar_pop (TV_CGRAPH_VERIFY);
}

/* Verify symbol table for internal consistency.  */

DEBUG_FUNCTION void
symtab_node::verify_symtab_nodes (void)
{
  symtab_node *node;
  hash_map<tree, symtab_node *> comdat_head_map (251);
  asm_node *anode;

  for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
    if (anode->order < 0 || anode->order >= symtab->order)
       {
	  error ("invalid order in asm node %i", anode->order);
	  internal_error ("symtab_node::verify failed");
       }

  FOR_EACH_SYMBOL (node)
    {
      node->verify ();
      if (node->get_comdat_group ())
	{
	  symtab_node **entry, *s;
	  bool existed;

	  entry = &comdat_head_map.get_or_insert (node->get_comdat_group (),
						  &existed);
	  if (!existed)
	    *entry = node;
	  else if (!DECL_EXTERNAL (node->decl))
	    {
	      for (s = (*entry)->same_comdat_group;
		   s != NULL && s != node && s != *entry;
		   s = s->same_comdat_group)
		;
	      if (!s || s == *entry)
		{
		  error ("Two symbols with same comdat_group are not linked by "
			 "the same_comdat_group list.");
		  (*entry)->debug ();
		  node->debug ();
		  internal_error ("symtab_node::verify failed");
		}
	    }
	}
    }
}

#if __GNUC__ >= 10
#  pragma GCC diagnostic pop
#endif

/* Make DECL local.  FIXME: We shouldn't need to mess with rtl this early,
   but other code such as notice_global_symbol generates rtl.  */

void
symtab_node::make_decl_local (void)
{
  rtx rtl, symbol;

  if (weakref)
    {
      weakref = false;
      IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl)) = 0;
      TREE_CHAIN (DECL_ASSEMBLER_NAME (decl)) = NULL_TREE;
      symtab->change_decl_assembler_name
	 (decl, DECL_ASSEMBLER_NAME (get_alias_target ()->decl));
      DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
						 DECL_ATTRIBUTES (decl));
    }
  /* Avoid clearing comdat_groups on comdat-local decls.  */
  else if (TREE_PUBLIC (decl) == 0)
    return;

  /* Localizing a symbol also make all its transparent aliases local.  */
  ipa_ref *ref;
  for (unsigned i = 0; iterate_direct_aliases (i, ref); i++)
    {
      struct symtab_node *alias = ref->referring;
      if (alias->transparent_alias)
	alias->make_decl_local ();
    }

  if (VAR_P (decl))
    {
      DECL_COMMON (decl) = 0;
      /* ADDRESSABLE flag is not defined for public symbols.  */
      TREE_ADDRESSABLE (decl) = 1;
      TREE_STATIC (decl) = 1;
    }
  else
    gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);

  DECL_COMDAT (decl) = 0;
  DECL_WEAK (decl) = 0;
  DECL_EXTERNAL (decl) = 0;
  DECL_VISIBILITY_SPECIFIED (decl) = 0;
  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
  TREE_PUBLIC (decl) = 0;
  DECL_DLLIMPORT_P (decl) = 0;
  if (!DECL_RTL_SET_P (decl))
    return;

  /* Update rtl flags.  */
  make_decl_rtl (decl);

  rtl = DECL_RTL (decl);
  if (!MEM_P (rtl))
    return;

  symbol = XEXP (rtl, 0);
  if (GET_CODE (symbol) != SYMBOL_REF)
    return;

  SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}

/* Copy visibility from N.
   This is useful when THIS becomes a transparent alias of N.  */

void
symtab_node::copy_visibility_from (symtab_node *n)
{
  gcc_checking_assert (n->weakref == weakref);

  ipa_ref *ref;
  for (unsigned i = 0; iterate_direct_aliases (i, ref); i++)
    {
      struct symtab_node *alias = ref->referring;
      if (alias->transparent_alias)
	alias->copy_visibility_from (n);
    }

  if (VAR_P (decl))
    {
      DECL_COMMON (decl) = DECL_COMMON (n->decl);
      /* ADDRESSABLE flag is not defined for public symbols.  */
      if (TREE_PUBLIC (decl) && !TREE_PUBLIC (n->decl))
        TREE_ADDRESSABLE (decl) = 1;
      TREE_STATIC (decl) = TREE_STATIC (n->decl);
    }
  else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);

  DECL_COMDAT (decl) = DECL_COMDAT (n->decl);
  DECL_WEAK (decl) = DECL_WEAK (n->decl);
  DECL_EXTERNAL (decl) = DECL_EXTERNAL (n->decl);
  DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (n->decl);
  DECL_VISIBILITY (decl) = DECL_VISIBILITY (n->decl);
  TREE_PUBLIC (decl) = TREE_PUBLIC (n->decl);
  DECL_DLLIMPORT_P (decl) = DECL_DLLIMPORT_P (n->decl);
  resolution = n->resolution;
  set_comdat_group (n->get_comdat_group ());
  set_section (*n);
  externally_visible = n->externally_visible;
  if (!DECL_RTL_SET_P (decl))
    return;

  /* Update rtl flags.  */
  make_decl_rtl (decl);

  rtx rtl = DECL_RTL (decl);
  if (!MEM_P (rtl))
    return;

  rtx symbol = XEXP (rtl, 0);
  if (GET_CODE (symbol) != SYMBOL_REF)
    return;

  SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}

/* Walk the alias chain to return the symbol NODE is alias of.
   If NODE is not an alias, return NODE.
   Assumes NODE is known to be alias.  */

symtab_node *
symtab_node::ultimate_alias_target_1 (enum availability *availability,
				      symtab_node *ref)
{
  bool transparent_p = false;

  /* To determine visibility of the target, we follow ELF semantic of aliases.
     Here alias is an alternative assembler name of a given definition. Its
     availability prevails the availability of its target (i.e. static alias of
     weak definition is available.

     Transparent alias is just alternative name of a given symbol used within
     one compilation unit and is translated prior hitting the object file.  It
     inherits the visibility of its target.
     Weakref is a different animal (and noweak definition is weak).

     If we ever get into supporting targets with different semantics, a target
     hook will be needed here.  */

  if (availability)
    {
      transparent_p = transparent_alias;
      if (!transparent_p)
	*availability = get_availability (ref);
      else
	*availability = AVAIL_NOT_AVAILABLE;
    }

  symtab_node *node = this;
  while (node)
    {
      if (node->alias && node->analyzed)
	node = node->get_alias_target ();
      else
	{
	  if (!availability || (!transparent_p && node->analyzed))
	    ;
	  else if (node->analyzed && !node->transparent_alias)
	    *availability = node->get_availability (ref);
	  else
	    *availability = AVAIL_NOT_AVAILABLE;
	  return node;
	}
      if (node && availability && transparent_p
	  && node->transparent_alias)
	{
	  *availability = node->get_availability (ref);
	  transparent_p = false;
	}
    }
  if (availability)
    *availability = AVAIL_NOT_AVAILABLE;
  return NULL;
}

/* C++ FE sometimes change linkage flags after producing same body aliases.

   FIXME: C++ produce implicit aliases for virtual functions and vtables that
   are obviously equivalent.  The way it is doing so is however somewhat
   kludgy and interferes with the visibility code. As a result we need to
   copy the visibility from the target to get things right.  */

void
symtab_node::fixup_same_cpp_alias_visibility (symtab_node *target)
{
  if (is_a <cgraph_node *> (this))
    {
      DECL_DECLARED_INLINE_P (decl)
	 = DECL_DECLARED_INLINE_P (target->decl);
      DECL_DISREGARD_INLINE_LIMITS (decl)
	 = DECL_DISREGARD_INLINE_LIMITS (target->decl);
    }
  /* FIXME: It is not really clear why those flags should not be copied for
     functions, too.  */
  else
    {
      DECL_WEAK (decl) = DECL_WEAK (target->decl);
      DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
      DECL_VISIBILITY (decl) = DECL_VISIBILITY (target->decl);
    }
  if (TREE_PUBLIC (decl))
    {
      tree group;

      DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl);
      DECL_COMDAT (decl) = DECL_COMDAT (target->decl);
      group = target->get_comdat_group ();
      set_comdat_group (group);
      if (group && !same_comdat_group)
	add_to_same_comdat_group (target);
    }
  externally_visible = target->externally_visible;
}

/* Set section, do not recurse into aliases.
   When one wants to change section of a symbol and its aliases,
   use set_section.  */

void
symtab_node::set_section_for_node (const char *section)
{
  const char *current = get_section ();

  if (current == section
      || (current && section
	  && !strcmp (current, section)))
    return;

  release_section_hash_entry (x_section);
  if (!section)
    {
      x_section = NULL;
      implicit_section = false;
      return;
    }
  if (!symtab->section_hash)
    symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
  section_hash_entry **slot = symtab->section_hash->find_slot_with_hash
    (section, htab_hash_string (section), INSERT);
  if (*slot)
    x_section = retain_section_hash_entry (*slot);
  else
    {
      int len = strlen (section);
      *slot = x_section = ggc_cleared_alloc<section_hash_entry> ();
      x_section->ref_count = 1;
      x_section->name = ggc_vec_alloc<char> (len + 1);
      memcpy (x_section->name, section, len + 1);
    }
}

/* Set the section of node THIS to be the same as the section
   of node OTHER.  Keep reference counts of the sections
   up-to-date as needed.  */

void
symtab_node::set_section_for_node (const symtab_node &other)
{
  if (x_section == other.x_section)
    return;
  if (get_section () && other.get_section ())
    gcc_checking_assert (strcmp (get_section (), other.get_section ()) != 0);
  release_section_hash_entry (x_section);
  if (other.x_section)
    x_section = retain_section_hash_entry (other.x_section);
  else
    {
      x_section = NULL;
      implicit_section = false;
    }
}

/* Workers for set_section.  */

bool
symtab_node::set_section_from_string (symtab_node *n, void *s)
{
  n->set_section_for_node ((char *)s);
  return false;
}

/* Set the section of node N to be the same as the section
   of node O.  */

bool
symtab_node::set_section_from_node (symtab_node *n, void *o)
{
  const symtab_node &other = *static_cast<const symtab_node *> (o);
  n->set_section_for_node (other);
  return false;
}

/* Set section of symbol and its aliases.  */

void
symtab_node::set_section (const char *section)
{
  gcc_assert (!this->alias || !this->analyzed);
  call_for_symbol_and_aliases
    (symtab_node::set_section_from_string, const_cast<char *>(section), true);
}

void
symtab_node::set_section (const symtab_node &other)
{
  call_for_symbol_and_aliases
    (symtab_node::set_section_from_node, const_cast<symtab_node *>(&other), true);
}

/* Return the initialization priority.  */

priority_type
symtab_node::get_init_priority ()
{
  if (!this->in_init_priority_hash)
    return DEFAULT_INIT_PRIORITY;

  symbol_priority_map *h = symtab->init_priority_hash->get (this);
  return h ? h->init : DEFAULT_INIT_PRIORITY;
}

/* Return the finalization priority.  */

priority_type
cgraph_node::get_fini_priority ()
{
  if (!this->in_init_priority_hash)
    return DEFAULT_INIT_PRIORITY;
  symbol_priority_map *h = symtab->init_priority_hash->get (this);
  return h ? h->fini : DEFAULT_INIT_PRIORITY;
}

/* Return the initialization and finalization priority information for
   DECL.  If there is no previous priority information, a freshly
   allocated structure is returned.  */

symbol_priority_map *
symtab_node::priority_info (void)
{
  if (!symtab->init_priority_hash)
    symtab->init_priority_hash = hash_map<symtab_node *, symbol_priority_map>::create_ggc (13);

  bool existed;
  symbol_priority_map *h
    = &symtab->init_priority_hash->get_or_insert (this, &existed);
  if (!existed)
    {
      h->init = DEFAULT_INIT_PRIORITY;
      h->fini = DEFAULT_INIT_PRIORITY;
      in_init_priority_hash = true;
    }

  return h;
}

/* Set initialization priority to PRIORITY.  */

void
symtab_node::set_init_priority (priority_type priority)
{
  symbol_priority_map *h;

  if (is_a <cgraph_node *> (this))
    gcc_assert (DECL_STATIC_CONSTRUCTOR (this->decl));

  if (priority == DEFAULT_INIT_PRIORITY)
    {
      gcc_assert (get_init_priority() == priority);
      return;
    }
  h = priority_info ();
  h->init = priority;
}

/* Set finalization priority to PRIORITY.  */

void
cgraph_node::set_fini_priority (priority_type priority)
{
  symbol_priority_map *h;

  gcc_assert (DECL_STATIC_DESTRUCTOR (this->decl));

  if (priority == DEFAULT_INIT_PRIORITY)
    {
      gcc_assert (get_fini_priority() == priority);
      return;
    }
  h = priority_info ();
  h->fini = priority;
}

/* Worker for symtab_resolve_alias.  */

bool
symtab_node::set_implicit_section (symtab_node *n,
				   void *data ATTRIBUTE_UNUSED)
{
  n->implicit_section = true;
  return false;
}

/* Add reference recording that symtab node is alias of TARGET.
   The function can fail in the case of aliasing cycles; in this case
   it returns false.  */

bool
symtab_node::resolve_alias (symtab_node *target, bool transparent)
{
  symtab_node *n;

  gcc_assert (!analyzed && !ref_list.references.length ());

  /* Never let cycles to creep into the symbol table alias references;
     those will make alias walkers to be infinite.  */
  for (n = target; n && n->alias;
       n = n->analyzed ? n->get_alias_target () : NULL)
    if (n == this)
       {
	 if (is_a <cgraph_node *> (this))
	   error ("function %q+D part of alias cycle", decl);
	 else if (is_a <varpool_node *> (this))
	   error ("variable %q+D part of alias cycle", decl);
	 else
	   gcc_unreachable ();
	 alias = false;
	 return false;
       }

  /* "analyze" the node - i.e. mark the reference.  */
  definition = true;
  alias = true;
  analyzed = true;
  transparent |= transparent_alias;
  transparent_alias = transparent;
  if (transparent)
    while (target->transparent_alias && target->analyzed)
      target = target->get_alias_target ();
  create_reference (target, IPA_REF_ALIAS, NULL);

  /* Add alias into the comdat group of its target unless it is already there.  */
  if (same_comdat_group)
    remove_from_same_comdat_group ();
  set_comdat_group (NULL);
  if (target->get_comdat_group ())
    add_to_same_comdat_group (target);

  if ((get_section () != target->get_section ()
       || target->get_comdat_group ()) && get_section () && !implicit_section)
    {
      error ("section of alias %q+D must match section of its target", decl);
    }
  set_section (*target);
  if (target->implicit_section)
    call_for_symbol_and_aliases (set_implicit_section, NULL, true);

  /* Alias targets become redundant after alias is resolved into an reference.
     We do not want to keep it around or we would have to mind updating them
     when renaming symbols.  */
  alias_target = NULL;

  if (!transparent && cpp_implicit_alias && symtab->state >= CONSTRUCTION)
    fixup_same_cpp_alias_visibility (target);

  /* If alias has address taken, so does the target.  */
  if (address_taken)
    target->ultimate_alias_target ()->address_taken = true;

  /* All non-transparent aliases of THIS are now in fact aliases of TARGET.
     If alias is transparent, also all transparent aliases of THIS are now
     aliases of TARGET.
     Also merge same comdat group lists.  */
  ipa_ref *ref;
  for (unsigned i = 0; iterate_direct_aliases (i, ref);)
    {
      struct symtab_node *alias_alias = ref->referring;
      if (alias_alias->get_comdat_group ())
	{
	  alias_alias->remove_from_same_comdat_group ();
	  alias_alias->set_comdat_group (NULL);
	  if (target->get_comdat_group ())
	    alias_alias->add_to_same_comdat_group (target);
	}
      if ((!alias_alias->transparent_alias
	   && !alias_alias->symver)
	  || transparent)
	{
	  alias_alias->remove_all_references ();
	  alias_alias->create_reference (target, IPA_REF_ALIAS, NULL);
	}
      else i++;
    }
  return true;
}

/* Worker searching noninterposable alias.  */

bool
symtab_node::noninterposable_alias (symtab_node *node, void *data)
{
  if (!node->transparent_alias && decl_binds_to_current_def_p (node->decl))
    {
      symtab_node *fn = node->ultimate_alias_target ();

      /* Ensure that the alias is well formed this may not be the case
	 of user defined aliases and currently it is not always the case
	 of C++ same body aliases (that is a bug).  */
      if (TREE_TYPE (node->decl) != TREE_TYPE (fn->decl)
	  || DECL_CONTEXT (node->decl) != DECL_CONTEXT (fn->decl)
	  || (TREE_CODE (node->decl) == FUNCTION_DECL
	      && flags_from_decl_or_type (node->decl)
		 != flags_from_decl_or_type (fn->decl))
	  || DECL_ATTRIBUTES (node->decl) != DECL_ATTRIBUTES (fn->decl))
	return false;
      *(symtab_node **)data = node;
      return true;
    }
  return false;
}

/* If node cannot be overwriten by static or dynamic linker to point to
   different definition, return NODE. Otherwise look for alias with such
   property and if none exists, introduce new one.  */

symtab_node *
symtab_node::noninterposable_alias (void)
{
  tree new_decl;
  symtab_node *new_node = NULL;

  /* First try to look up existing alias or base object
     (if that is already non-overwritable).  */
  symtab_node *node = ultimate_alias_target ();
  gcc_assert (!node->alias && !node->weakref);
  node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias,
				     (void *)&new_node, true);
  if (new_node)
    return new_node;

  /* If aliases aren't supported by the assembler, fail.  */
  if (!TARGET_SUPPORTS_ALIASES)
    return NULL;
  else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl)))
    return NULL;

  /* Otherwise create a new one.  */
  new_decl = copy_node (node->decl);
  DECL_DLLIMPORT_P (new_decl) = 0;
  tree name = clone_function_name (node->decl, "localalias");
  if (!flag_wpa)
    {
      unsigned long num = 0;
      /* In the rare case we already have a localalias, but the above
	 node->call_for_symbol_and_aliases call didn't find any suitable,
	 iterate until we find one not used yet.  */
      while (symtab_node::get_for_asmname (name))
	name = clone_function_name (node->decl, "localalias", num++);
    }
  DECL_NAME (new_decl) = name;
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (new_decl) = NULL;
  DECL_INITIAL (new_decl) = NULL;
  SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
  SET_DECL_RTL (new_decl, NULL);

  /* Update the properties.  */
  DECL_EXTERNAL (new_decl) = 0;
  TREE_PUBLIC (new_decl) = 0;
  DECL_COMDAT (new_decl) = 0;
  DECL_WEAK (new_decl) = 0;

  /* Since the aliases can be added to vtables, keep DECL_VIRTUAL flag.  */
  DECL_VIRTUAL_P (new_decl) = DECL_VIRTUAL_P (node->decl);
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    {
      DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
      DECL_STATIC_DESTRUCTOR (new_decl) = 0;
      new_node = cgraph_node::create_alias (new_decl, node->decl);

      cgraph_node *new_cnode = dyn_cast <cgraph_node *> (new_node),
		   *cnode = dyn_cast <cgraph_node *> (node);

      new_cnode->unit_id = cnode->unit_id;
      new_cnode->merged_comdat = cnode->merged_comdat;
      new_cnode->merged_extern_inline = cnode->merged_extern_inline;
    }
  else
    {
      TREE_READONLY (new_decl) = TREE_READONLY (node->decl);
      DECL_INITIAL (new_decl) = error_mark_node;
      new_node = varpool_node::create_alias (new_decl, node->decl);
    }
  new_node->resolve_alias (node);
  gcc_assert (decl_binds_to_current_def_p (new_decl)
	      && targetm.binds_local_p (new_decl));
  return new_node;
}

/* Return true if symtab node and TARGET represents
   semantically equivalent symbols.  */

bool
symtab_node::semantically_equivalent_p (symtab_node *target)
{
  enum availability avail;
  symtab_node *ba;
  symtab_node *bb;

  /* Equivalent functions are equivalent.  */
  if (decl == target->decl)
    return true;

  /* If symbol is not overwritable by different implementation,
     walk to the base object it defines.  */
  ba = ultimate_alias_target (&avail);
  if (avail >= AVAIL_AVAILABLE)
    {
      if (target == ba)
	return true;
    }
  else
    ba = this;
  bb = target->ultimate_alias_target (&avail);
  if (avail >= AVAIL_AVAILABLE)
    {
      if (this == bb)
	return true;
    }
  else
    bb = target;
  return bb == ba;
}

/* Classify symbol symtab node for partitioning.  */

enum symbol_partitioning_class
symtab_node::get_partitioning_class (void)
{
  /* Inline clones are always duplicated.
     This include external declarations.   */
  cgraph_node *cnode = dyn_cast <cgraph_node *> (this);

  if (DECL_ABSTRACT_P (decl))
    return SYMBOL_EXTERNAL;

  if (cnode && (cnode->inlined_to || cnode->declare_variant_alt))
    return SYMBOL_DUPLICATE;

  /* Transparent aliases are always duplicated.  */
  if (transparent_alias)
    return definition ? SYMBOL_DUPLICATE : SYMBOL_EXTERNAL;

  /* External declarations are external.  */
  if (DECL_EXTERNAL (decl))
    return SYMBOL_EXTERNAL;

  /* Even static aliases of external functions as external.  Those can happen
     when COMDAT got resolved to non-IL implementation.  */
  if (alias && DECL_EXTERNAL (ultimate_alias_target ()->decl))
    return SYMBOL_EXTERNAL;

  if (varpool_node *vnode = dyn_cast <varpool_node *> (this))
    {
      if (alias && definition && !ultimate_alias_target ()->definition)
	return SYMBOL_EXTERNAL;
      /* Constant pool references use local symbol names that cannot
         be promoted global.  We should never put into a constant pool
         objects that cannot be duplicated across partitions.  */
      if (DECL_IN_CONSTANT_POOL (decl))
	return SYMBOL_DUPLICATE;
      if (DECL_HARD_REGISTER (decl))
	return SYMBOL_DUPLICATE;
      gcc_checking_assert (vnode->definition);
    }
  /* Functions that are cloned may stay in callgraph even if they are unused.
     Handle them as external; compute_ltrans_boundary take care to make
     proper things to happen (i.e. to make them appear in the boundary but
     with body streamed, so clone can me materialized).  */
  else if (!dyn_cast <cgraph_node *> (this)->function_symbol ()->definition)
    return SYMBOL_EXTERNAL;

  /* Linker discardable symbols are duplicated to every use unless they are
     keyed.  */
  if (DECL_ONE_ONLY (decl)
      && !force_output
      && !forced_by_abi
      && !used_from_object_file_p ())
    return SYMBOL_DUPLICATE;

  return SYMBOL_PARTITION;
}

/* Return true when symbol is known to be non-zero.  */

bool
symtab_node::nonzero_address ()
{
  /* Weakrefs may be NULL when their target is not defined.  */
  if (alias && weakref)
    {
      if (analyzed)
	{
	  symtab_node *target = ultimate_alias_target ();

	  if (target->alias && target->weakref)
	    return false;
	  /* We cannot recurse to target::nonzero.  It is possible that the
	     target is used only via the alias.
	     We may walk references and look for strong use, but we do not know
	     if this strong use will survive to final binary, so be
	     conservative here.  
	     ??? Maybe we could do the lookup during late optimization that
	     could be useful to eliminate the NULL pointer checks in LTO
	     programs.  */
	  if (target->definition && !DECL_EXTERNAL (target->decl))
	      return true;
	  if (target->resolution != LDPR_UNKNOWN
	      && target->resolution != LDPR_UNDEF
	      && !target->can_be_discarded_p ()
	      && flag_delete_null_pointer_checks)
	    return true;
	  return false;
	}
      else
        return false;
    }

  /* With !flag_delete_null_pointer_checks we assume that symbols may
     bind to NULL. This is on by default on embedded targets only.

     Otherwise all non-WEAK symbols must be defined and thus non-NULL or
     linking fails.  Important case of WEAK we want to do well are comdats,
     which also must be defined somewhere.

     When parsing, beware the cases when WEAK attribute is added later.  */
  if ((!DECL_WEAK (decl) || DECL_COMDAT (decl))
      && flag_delete_null_pointer_checks)
    {
      refuse_visibility_changes = true;
      return true;
    }

  /* If target is defined and not extern, we know it will be
     output and thus it will bind to non-NULL.
     Play safe for flag_delete_null_pointer_checks where weak definition may
     be re-defined by NULL.  */
  if (definition && !DECL_EXTERNAL (decl)
      && (flag_delete_null_pointer_checks || !DECL_WEAK (decl)))
    {
      if (!DECL_WEAK (decl))
        refuse_visibility_changes = true;
      return true;
    }

  /* As the last resort, check the resolution info.  */
  if (resolution != LDPR_UNKNOWN
      && resolution != LDPR_UNDEF
      && !can_be_discarded_p ()
      && flag_delete_null_pointer_checks)
    return true;
  return false;
}

/* Return 0 if symbol is known to have different address than S2,
   Return 1 if symbol is known to have same address as S2,
   return -1 otherwise.  

   If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
   and S2 is going to be accessed.  This eliminates the situations when
   either THIS or S2 is NULL and is useful for comparing bases when deciding
   about memory aliasing.  */
int
symtab_node::equal_address_to (symtab_node *s2, bool memory_accessed)
{
  enum availability avail1, avail2;

  /* A Shortcut: equivalent symbols are always equivalent.  */
  if (this == s2)
    return 1;

  /* Unwind transparent aliases first; those are always equal to their
     target.  */
  if (this->transparent_alias && this->analyzed)
    return this->get_alias_target ()->equal_address_to (s2);
  while (s2->transparent_alias && s2->analyzed)
    s2 = s2->get_alias_target();

  if (this == s2)
    return 1;

  /* For non-interposable aliases, lookup and compare their actual definitions.
     Also check if the symbol needs to bind to given definition.  */
  symtab_node *rs1 = ultimate_alias_target (&avail1);
  symtab_node *rs2 = s2->ultimate_alias_target (&avail2);
  bool binds_local1 = rs1->analyzed && decl_binds_to_current_def_p (this->decl);
  bool binds_local2 = rs2->analyzed && decl_binds_to_current_def_p (s2->decl);
  bool really_binds_local1 = binds_local1;
  bool really_binds_local2 = binds_local2;

  /* Addresses of vtables and virtual functions cannot be used by user
     code and are used only within speculation.  In this case we may make
     symbol equivalent to its alias even if interposition may break this
     rule.  Doing so will allow us to turn speculative inlining into
     non-speculative more aggressively.  */
  if (DECL_VIRTUAL_P (this->decl) && avail1 >= AVAIL_AVAILABLE)
    binds_local1 = true;
  if (DECL_VIRTUAL_P (s2->decl) && avail2 >= AVAIL_AVAILABLE)
    binds_local2 = true;

  /* If both definitions are available we know that even if they are bound
     to other unit they must be defined same way and therefore we can use
     equivalence test.  */
  if (rs1 != rs2 && avail1 >= AVAIL_AVAILABLE && avail2 >= AVAIL_AVAILABLE)
    binds_local1 = binds_local2 = true;

  if (binds_local1 && binds_local2 && rs1 == rs2)
    {
      /* We made use of the fact that alias is not weak.  */
      if (rs1 != this)
        refuse_visibility_changes = true;
      if (rs2 != s2)
        s2->refuse_visibility_changes = true;
      return 1;
    }

  /* If both symbols may resolve to NULL, we cannot really prove them
     different.  */
  if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ())
    return -1;

  /* Except for NULL, functions and variables never overlap.  */
  if (TREE_CODE (decl) != TREE_CODE (s2->decl))
    return 0;

  /* If one of the symbols is unresolved alias, punt.  */
  if (rs1->alias || rs2->alias)
    return -1;

  /* If we have a non-interposable definition of at least one of the symbols
     and the other symbol is different, we know other unit cannot interpose
     it to the first symbol; all aliases of the definition needs to be 
     present in the current unit.  */
  if (((really_binds_local1 || really_binds_local2)
      /* If we have both definitions and they are different, we know they
	 will be different even in units they binds to.  */
       || (binds_local1 && binds_local2))
      && rs1 != rs2)
    {
      /* We make use of the fact that one symbol is not alias of the other
	 and that the definition is non-interposable.  */
      refuse_visibility_changes = true;
      s2->refuse_visibility_changes = true;
      rs1->refuse_visibility_changes = true;
      rs2->refuse_visibility_changes = true;
      return 0;
    }

  if (rs1 == rs2)
    return -1;

  /* If the FE tells us at least one of the decls will never be aliased nor
     overlapping with other vars in some other way, return 0.  */
  if (VAR_P (decl)
      && (lookup_attribute ("non overlapping", DECL_ATTRIBUTES (decl))
	  || lookup_attribute ("non overlapping", DECL_ATTRIBUTES (s2->decl))))
    return 0;

  /* TODO: Alias oracle basically assume that addresses of global variables
     are different unless they are declared as alias of one to another while
     the code folding comparisons doesn't.
     We probably should be consistent and use this fact here, too, but for
     the moment return false only when we are called from the alias oracle.
     Return 0 in C constant initializers and C++ manifestly constant
     expressions, the likelyhood that different vars will be aliases is
     small and returning -1 lets us reject too many initializers.  */
  if (memory_accessed || folding_initializer)
    return 0;

  return -1;
}

/* Worker for call_for_symbol_and_aliases.  */

bool
symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *,
							      void *),
					    void *data,
					    bool include_overwritable)
{
  ipa_ref *ref;
  FOR_EACH_ALIAS (this, ref)
    {
      symtab_node *alias = ref->referring;
      if (include_overwritable
	  || alias->get_availability () > AVAIL_INTERPOSABLE)
	if (alias->call_for_symbol_and_aliases (callback, data,
					      include_overwritable))
	  return true;
    }
  return false;
}

/* Return true if address of N is possibly compared.  */

static bool
address_matters_1 (symtab_node *n, void *)
{
  struct ipa_ref *ref;

  if (!n->address_can_be_compared_p ())
    return false;
  if (n->externally_visible || n->force_output)
    return true;

  for (unsigned int i = 0; n->iterate_referring (i, ref); i++)
    if (ref->address_matters_p ())
      return true;
  return false;
}

/* Return true if symbol's address may possibly be compared to other
   symbol's address.  */

bool
symtab_node::address_matters_p ()
{
  gcc_assert (!alias);
  return call_for_symbol_and_aliases (address_matters_1, NULL, true);
}

/* Return true if symbol's alignment may be increased.  */

bool
symtab_node::can_increase_alignment_p (void)
{
  symtab_node *target = ultimate_alias_target ();

  /* For now support only variables.  */
  if (!VAR_P (decl))
    return false;

  /* With -fno-toplevel-reorder we may have already output the constant.  */
  if (TREE_ASM_WRITTEN (target->decl))
    return false;

  /* If target is already placed in an anchor, we cannot touch its
     alignment.  */
  if (DECL_RTL_SET_P (target->decl)
      && MEM_P (DECL_RTL (target->decl))
      && SYMBOL_REF_HAS_BLOCK_INFO_P (XEXP (DECL_RTL (target->decl), 0)))
    return false;

  /* Constant pool entries may be shared.  */
  if (DECL_IN_CONSTANT_POOL (target->decl))
    return false;

  /* We cannot change alignment of symbols that may bind to symbols
     in other translation unit that may contain a definition with lower
     alignment.  */
  if (!decl_binds_to_current_def_p (decl))
    return false;

  /* When compiling partition, be sure the symbol is not output by other
     partition.  */
  if (flag_ltrans
      && (target->in_other_partition
	  || target->get_partitioning_class () == SYMBOL_DUPLICATE))
    return false;

  /* Do not override the alignment as specified by the ABI when the used
     attribute is set.  */
  if (DECL_PRESERVE_P (decl) || DECL_PRESERVE_P (target->decl))
    return false;

  /* Do not override explicit alignment set by the user when an explicit
     section name is also used.  This is a common idiom used by many
     software projects.  */
  if (DECL_SECTION_NAME (target->decl) != NULL && !target->implicit_section)
    return false;

  return true;
}

/* Worker for symtab_node::increase_alignment.  */

static bool
increase_alignment_1 (symtab_node *n, void *v)
{
  unsigned int align = (size_t)v;
  if (DECL_ALIGN (n->decl) < align
      && n->can_increase_alignment_p ())
    {
      SET_DECL_ALIGN (n->decl, align);
      DECL_USER_ALIGN (n->decl) = 1;
    }
  return false;
}

/* Increase alignment of THIS to ALIGN.  */

void
symtab_node::increase_alignment (unsigned int align)
{
  gcc_assert (can_increase_alignment_p () && align <= MAX_OFILE_ALIGNMENT);
  ultimate_alias_target()->call_for_symbol_and_aliases (increase_alignment_1,
						        (void *)(size_t) align,
						        true);
  gcc_assert (DECL_ALIGN (decl) >= align);
}

/* Helper for symtab_node::definition_alignment.  */

static bool
get_alignment_1 (symtab_node *n, void *v)
{
  *((unsigned int *)v) = MAX (*((unsigned int *)v), DECL_ALIGN (n->decl));
  return false;
}

/* Return desired alignment of the definition.  This is NOT alignment useful
   to access THIS, because THIS may be interposable and DECL_ALIGN should
   be used instead.  It however must be guaranteed when output definition
   of THIS.  */

unsigned int
symtab_node::definition_alignment ()
{
  unsigned int align = 0;
  gcc_assert (!alias);
  call_for_symbol_and_aliases (get_alignment_1, &align, true);
  return align;
}

/* Return symbol used to separate symbol name from suffix.  */

char 
symbol_table::symbol_suffix_separator ()
{
#ifndef NO_DOT_IN_LABEL
  return '.';
#elif !defined NO_DOLLAR_IN_LABEL
  return '$';
#else
  return '_';
#endif
}

/* Return true when references to this symbol from REF must bind to current
   definition in final executable.  */

bool
symtab_node::binds_to_current_def_p (symtab_node *ref)
{
  if (!definition && !in_other_partition)
    return false;
  if (transparent_alias)
    return definition
	   && get_alias_target()->binds_to_current_def_p (ref);
  cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
  if (cnode && cnode->ifunc_resolver)
    return false;
  if (decl_binds_to_current_def_p (decl))
    return true;

  /* Inline clones always binds locally.  */
  if (cnode && cnode->inlined_to)
    return true;

  if (DECL_EXTERNAL (decl))
    return false;

  gcc_assert (externally_visible);

  if (ref)
    {
      cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
      if (cref)
	ref = cref->inlined_to;
    }

  /* If this is a reference from symbol itself and there are no aliases, we
     may be sure that the symbol was not interposed by something else because
     the symbol itself would be unreachable otherwise.  This is important
     to optimize recursive functions well.

     This assumption may be broken by inlining: if symbol is interposable
     but the body is available (i.e. declared inline), inliner may make
     the body reachable even with interposition.  */
  if (this == ref && !has_aliases_p ()
      && (!cnode
	  || symtab->state >= IPA_SSA_AFTER_INLINING
	  || get_availability () >= AVAIL_INTERPOSABLE))
    return true;


  /* References within one comdat group are always bound in a group.  */
  if (ref
      && symtab->state >= IPA_SSA_AFTER_INLINING
      && get_comdat_group ()
      && get_comdat_group () == ref->get_comdat_group ())
    return true;

  return false;
}

/* Return true if symbol should be output to the symbol table.  */

bool
symtab_node::output_to_lto_symbol_table_p (void)
{
  /* Only externally visible symbols matter.  */
  if (!TREE_PUBLIC (decl))
    return false;
  if (!real_symbol_p ())
    return false;
  /* FIXME: variables probably should not be considered as real symbols at
     first place.  */
  if (VAR_P (decl) && DECL_HARD_REGISTER (decl))
    return false;
  if (TREE_CODE (decl) == FUNCTION_DECL && !definition
      && fndecl_built_in_p (decl))
    {
      /* Builtins like those for most math functions have actual implementations
	 in libraries so make sure to output references into the symbol table to
	 make those libraries referenced.  Note this is incomplete handling for
	 now and only covers math functions.  */
      return builtin_with_linkage_p (decl);
    }

  /* We have real symbol that should be in symbol table.  However try to trim
     down the references to libraries bit more because linker will otherwise
     bring unnecessary object files into the final link.
     FIXME: The following checks can easily be confused i.e. by self recursive
     function or self-referring variable.  */

  /* We keep external functions in symtab for sake of inlining
     and devirtualization.  We do not want to see them in symbol table as
     references unless they are really used.  */
  cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
  if (cnode && (!definition || DECL_EXTERNAL (decl))
      && cnode->callers)
    return true;

 /* Ignore all references from external vars initializers - they are not really
    part of the compilation unit until they are used by folding.  Some symbols,
    like references to external construction vtables cannot be referred to at
    all.  We decide this at can_refer_decl_in_current_unit_p.  */
 if (!definition || DECL_EXTERNAL (decl))
    {
      int i;
      struct ipa_ref *ref;
      for (i = 0; iterate_referring (i, ref); i++)
	{
	  if (ref->use == IPA_REF_ALIAS)
	    continue;
          if (is_a <cgraph_node *> (ref->referring))
	    return true;
	  if (!DECL_EXTERNAL (ref->referring->decl))
	    return true;
	}
      return false;
    }
  return true;
}
