/* Symbol table.
   Copyright (C) 2012-2020 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);
}

/* 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.  */

void
symtab_node::unregister (void)
{
  remove_all_references ();
  remove_all_referring ();

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

  remove_from_same_comdat_group ();

  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 ();
      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 = vec_safe_address (list->references);
  vec_safe_grow (list->references, vec_safe_length (list->references) + 1);
  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.
   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;
      }
}

/* Remove all references in ref list.  */

void
symtab_node::remove_all_references (void)
{
  while (vec_safe_length (ref_list.references))
    ref_list.references->last ().remove_reference ();
  vec_free (ref_list.references);
}

/* 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 (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);

  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 ());
  call_for_symbol_and_aliases (symtab_node::set_section,
			     const_cast<char *>(n->get_section ()), true);
  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 ();
  section_hash_entry **slot;

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

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

/* Worker for set_section.  */

bool
symtab_node::set_section (symtab_node *n, void *s)
{
  n->set_section_for_node ((char *)s);
  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, const_cast<char *>(section), 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 && !vec_safe_length (ref_list.references));

  /* Never let cycles to creep into the symbol table alias references;
     those will make alias walkers to be infinite.  */
  for (n = target; n && n->alias;
       n = n->analyzed ? 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);
    }
  call_for_symbol_and_aliases (symtab_node::set_section,
			     const_cast<char *>(target->get_section ()), true);
  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)
    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)
    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;
}
