/* Symbol table.
   Copyright (C) 2012-2021 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"

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.c 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 ());
  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 (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;

  /* 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-interposale 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;
    }

  /* 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 memory_accessed && rs1 != rs2 ? 0 : -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.  */
      if (builtin_with_linkage_p (decl))
	return true;
      else
	return false;
    }

  /* 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;
}
