/* Symbol table.
   Copyright (C) 2012-2014 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 "tm.h"
#include "rtl.h"
#include "tree.h"
#include "print-tree.h"
#include "varasm.h"
#include "function.h"
#include "emit-rtl.h"
#include "basic-block.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple-expr.h"
#include "is-a.h"
#include "gimple.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "hashtab.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "timevar.h"
#include "lto-streamer.h"
#include "output.h"

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"
};

/* Hash table used to convert declarations into nodes.  */
static GTY((param_is (symtab_node))) htab_t symtab_hash;
/* Hash table used to convert assembler names into nodes.  */
static GTY((param_is (symtab_node))) htab_t assembler_name_hash;

/* Linked list of symbol table nodes.  */
symtab_node *symtab_nodes;

/* The order index of the next symtab node to be created.  This is
   used so that we can sort the cgraph nodes in order by when we saw
   them, to support -fno-toplevel-reorder.  */
int symtab_order;

/* Returns a hash code for P.  */

static hashval_t
hash_node (const void *p)
{
  const symtab_node *n = (const symtab_node *) p;
  return (hashval_t) DECL_UID (n->decl);
}


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

static int
eq_node (const void *p1, const void *p2)
{
  const symtab_node *n1 = (const symtab_node *) p1;
  const symtab_node *n2 = (const symtab_node *) p2;
  return DECL_UID (n1->decl) == DECL_UID (n2->decl);
}

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

hashval_t
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));
}


/* Returns a hash code for P.  */

static hashval_t
hash_node_by_assembler_name (const void *p)
{
  const symtab_node *n = (const symtab_node *) p;
  return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
}

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

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

  if (decl_asmname == asmname)
    return true;

  decl_str = IDENTIFIER_POINTER (decl_asmname);
  asmname_str = IDENTIFIER_POINTER (asmname);


  /* If the target assembler name was set by the user, things are trickier.
     We have a leading '*' to begin with.  After that, it's arguable what
     is the correct thing to do with -fleading-underscore.  Arguably, we've
     historically been doing the wrong thing in assemble_alias by always
     printing the leading underscore.  Since we're not changing that, make
     sure user_label_prefix follows the '*' before matching.  */
  if (decl_str[0] == '*')
    {
      size_t ulp_len = strlen (user_label_prefix);

      decl_str ++;

      if (ulp_len == 0)
	test = true;
      else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
	decl_str += ulp_len, test=true;
      else
	decl_str --;
    }
  if (asmname_str[0] == '*')
    {
      size_t ulp_len = strlen (user_label_prefix);

      asmname_str ++;

      if (ulp_len == 0)
	test = true;
      else if (strncmp (asmname_str, user_label_prefix, ulp_len) == 0)
	asmname_str += ulp_len, test=true;
      else
	asmname_str --;
    }

  if (!test)
    return false;
  return strcmp (decl_str, asmname_str) == 0;
}


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

static int
eq_assembler_name (const void *p1, const void *p2)
{
  const symtab_node *n1 = (const symtab_node *) p1;
  const_tree name = (const_tree)p2;
  return (decl_assembler_name_equal (n1->decl, name));
}

/* Insert NODE to assembler name hash.  */

void
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)
    {
      void **aslot;
      struct cgraph_node *cnode;
      tree decl = node->decl;

      tree name = DECL_ASSEMBLER_NAME (node->decl);

      aslot = htab_find_slot_with_hash (assembler_name_hash, name,
					decl_assembler_name_hash (name),
					INSERT);
      gcc_assert (*aslot != node);
      node->next_sharing_asm_name = (symtab_node *)*aslot;
      if (*aslot != NULL)
	((symtab_node *)*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
unlink_from_assembler_name_hash (symtab_node *node, bool with_clones)
{
  if (assembler_name_hash)
    {
      struct 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);
          void **slot;
	  slot = htab_find_slot_with_hash (assembler_name_hash, name,
					   decl_assembler_name_hash (name),
					   NO_INSERT);
	  gcc_assert (*slot == node);
	  if (!node->next_sharing_asm_name)
	    htab_clear_slot (assembler_name_hash, 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
symtab_prevail_in_asm_name_hash (symtab_node *node)
{
  unlink_from_assembler_name_hash (node, false);
  insert_to_assembler_name_hash (node, false);
}


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

void
symtab_register_node (symtab_node *node)
{
  struct symtab_node key;
  symtab_node **slot;

  node->next = symtab_nodes;
  node->previous = NULL;
  if (symtab_nodes)
    symtab_nodes->previous = node;
  symtab_nodes = node;

  if (!symtab_hash)
    symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
  key.decl = node->decl;
  slot = (symtab_node **) htab_find_slot (symtab_hash, &key, INSERT);
  if (*slot == NULL)
    *slot = node;

  ipa_empty_ref_list (&node->ref_list);

  node->order = symtab_order++;

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

/* Make NODE to be the one symtab hash is pointing to.  Used when reshaping tree
   of inline clones.  */

void
symtab_insert_node_to_hashtable (symtab_node *node)
{
  struct symtab_node key;
  symtab_node **slot;

  if (!symtab_hash)
    symtab_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
  key.decl = node->decl;
  slot = (symtab_node **) htab_find_slot (symtab_hash, &key, INSERT);
  *slot = node;
}

/* Remove NODE from same comdat group.   */

void
symtab_remove_from_same_comdat_group (symtab_node *node)
{
  if (node->same_comdat_group)
    {
      symtab_node *prev;
      for (prev = node->same_comdat_group;
	   prev->same_comdat_group != node;
	   prev = prev->same_comdat_group)
	;
      if (node->same_comdat_group == prev)
	prev->same_comdat_group = NULL;
      else
	prev->same_comdat_group = node->same_comdat_group;
      node->same_comdat_group = NULL;
    }
}

/* Remove node from symbol table.  This function is not used directly, but via
   cgraph/varpool node removal routines.  */

void
symtab_unregister_node (symtab_node *node)
{
  void **slot;
  ipa_remove_all_references (&node->ref_list);
  ipa_remove_all_referring (&node->ref_list);

  symtab_remove_from_same_comdat_group (node);

  if (node->previous)
    node->previous->next = node->next;
  else
    symtab_nodes = node->next;
  if (node->next)
    node->next->previous = node->previous;
  node->next = NULL;
  node->previous = NULL;

  slot = htab_find_slot (symtab_hash, node, NO_INSERT);

  /* During LTO symtab merging we temporarily corrupt decl to symtab node
     hash.  */
  gcc_assert ((slot && *slot) || in_lto_p);
  if (slot && *slot && *slot == node)
    {
      symtab_node *replacement_node = NULL;
      if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
	replacement_node = cgraph_find_replacement_node (cnode);
      if (!replacement_node)
	htab_clear_slot (symtab_hash, slot);
      else
	*slot = replacement_node;
    }
  if (!is_a <varpool_node> (node) || !DECL_HARD_REGISTER (node->decl))
    unlink_from_assembler_name_hash (node, false);
}

/* Return symbol table node associated with DECL, if any,
   and NULL otherwise.  */

symtab_node *
symtab_get_node (const_tree decl)
{
  symtab_node **slot;
  struct symtab_node key;

#ifdef ENABLE_CHECKING
  /* Check that we are called for sane type of object - functions
     and static or external variables.  */
  gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
		       || (TREE_CODE (decl) == VAR_DECL
			   && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
			       || in_lto_p)));
#endif

  if (!symtab_hash)
    return NULL;

  key.decl = CONST_CAST2 (tree, const_tree, decl);

  slot = (symtab_node **) htab_find_slot (symtab_hash, &key,
					 NO_INSERT);

  if (slot)
    return *slot;
  return NULL;
}

/* Remove symtab NODE from the symbol table.  */

void
symtab_remove_node (symtab_node *node)
{
  if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
    cgraph_remove_node (cnode);
  else if (varpool_node *vnode = dyn_cast <varpool_node> (node))
    varpool_remove_node (vnode);
}

/* Initalize asm name hash unless.  */

void
symtab_initialize_asm_name_hash (void)
{
  symtab_node *node;
  if (!assembler_name_hash)
    {
      assembler_name_hash =
	htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
			 NULL);
      FOR_EACH_SYMBOL (node)
	insert_to_assembler_name_hash (node, false);
    }
}

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

symtab_node *
symtab_node_for_asm (const_tree asmname)
{
  symtab_node *node;
  void **slot;

  symtab_initialize_asm_name_hash ();
  slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
				   decl_assembler_name_hash (asmname),
				   NO_INSERT);

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

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

void
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 ((TREE_CODE (decl) == VAR_DECL
       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
      || TREE_CODE (decl) == FUNCTION_DECL)
    node = symtab_get_node (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);
      if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
	  && DECL_RTL_SET_P (decl))
	warning (0, "%D 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 (node)
	insert_to_assembler_name_hash (node, true);
    }
}

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

void
symtab_add_to_same_comdat_group (symtab_node *new_node,
				 symtab_node *old_node)
{
  gcc_assert (DECL_ONE_ONLY (old_node->decl));
  gcc_assert (!new_node->same_comdat_group);
  gcc_assert (new_node != old_node);

  DECL_COMDAT_GROUP (new_node->decl) = DECL_COMDAT_GROUP (old_node->decl);
  new_node->same_comdat_group = old_node;
  if (!old_node->same_comdat_group)
    old_node->same_comdat_group = new_node;
  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 = new_node;
    }
}

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

void
symtab_dissolve_same_comdat_group_list (symtab_node *node)
{
  symtab_node *n = node;
  symtab_node *next;

  if (!node->same_comdat_group)
    return;
  do
    {
      next = n->same_comdat_group;
      n->same_comdat_group = NULL;
      /* Clear DECL_COMDAT_GROUP for comdat locals, since
         make_decl_local doesn't.  */
      if (!TREE_PUBLIC (n->decl))
	DECL_COMDAT_GROUP (n->decl) = NULL_TREE;
      n = next;
    }
  while (n != node);
}

/* 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 lang_hooks.decl_printable_name (decl, 2);
  return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
}

/* Return printable identifier name.  */

const char *
symtab_node::name () const
{
  return lang_hooks.decl_printable_name (decl, 2);
}

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

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

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

  fprintf (f, "%s/%i (%s)",
	   node->asm_name (),
	   node->order,
	   node->name ());
  dump_addr (f, " @", (void *)node);
  fprintf (f, "\n  Type: %s", symtab_type_names[node->type]);

  if (node->definition)
    fprintf (f, " definition");
  if (node->analyzed)
    fprintf (f, " analyzed");
  if (node->alias)
    fprintf (f, " alias");
  if (node->weakref)
    fprintf (f, " weakref");
  if (node->cpp_implicit_alias)
    fprintf (f, " cpp_implicit_alias");
  if (node->alias_target)
    fprintf (f, " target:%s",
	     DECL_P (node->alias_target) 
	     ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
				     (node->alias_target))
	     : IDENTIFIER_POINTER (node->alias_target));
  if (node->body_removed)
    fprintf (f, "\n  Body removed by symtab_remove_unreachable_nodes");
  fprintf (f, "\n  Visibility:");
  if (node->in_other_partition)
    fprintf (f, " in_other_partition");
  if (node->used_from_other_partition)
    fprintf (f, " used_from_other_partition");
  if (node->force_output)
    fprintf (f, " force_output");
  if (node->forced_by_abi)
    fprintf (f, " forced_by_abi");
  if (node->externally_visible)
    fprintf (f, " externally_visible");
  if (node->resolution != LDPR_UNKNOWN)
    fprintf (f, " %s",
 	     ld_plugin_symbol_resolution_names[(int)node->resolution]);
  if (TREE_ASM_WRITTEN (node->decl))
    fprintf (f, " asm_written");
  if (DECL_EXTERNAL (node->decl))
    fprintf (f, " external");
  if (TREE_PUBLIC (node->decl))
    fprintf (f, " public");
  if (DECL_COMMON (node->decl))
    fprintf (f, " common");
  if (DECL_WEAK (node->decl))
    fprintf (f, " weak");
  if (DECL_DLLIMPORT_P (node->decl))
    fprintf (f, " dll_import");
  if (DECL_COMDAT (node->decl))
    fprintf (f, " comdat");
  if (DECL_COMDAT_GROUP (node->decl))
    fprintf (f, " comdat_group:%s",
	     IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->decl)));
  if (DECL_ONE_ONLY (node->decl))
    fprintf (f, " one_only");
  if (DECL_SECTION_NAME (node->decl))
    fprintf (f, " section_name:%s",
	     TREE_STRING_POINTER (DECL_SECTION_NAME (node->decl)));
  if (DECL_VISIBILITY_SPECIFIED (node->decl))
    fprintf (f, " visibility_specified");
  if (DECL_VISIBILITY (node->decl))
    fprintf (f, " visibility:%s",
	     visibility_types [DECL_VISIBILITY (node->decl)]);
  if (DECL_VIRTUAL_P (node->decl))
    fprintf (f, " virtual");
  if (DECL_ARTIFICIAL (node->decl))
    fprintf (f, " artificial");
  if (TREE_CODE (node->decl) == FUNCTION_DECL)
    {
      if (DECL_STATIC_CONSTRUCTOR (node->decl))
	fprintf (f, " constructor");
      if (DECL_STATIC_DESTRUCTOR (node->decl))
	fprintf (f, " destructor");
    }
  fprintf (f, "\n");
  
  if (node->same_comdat_group)
    fprintf (f, "  Same comdat group as: %s/%i\n",
	     node->same_comdat_group->asm_name (),
	     node->same_comdat_group->order);
  if (node->next_sharing_asm_name)
    fprintf (f, "  next sharing asm name: %i\n",
	     node->next_sharing_asm_name->order);
  if (node->previous_sharing_asm_name)
    fprintf (f, "  previous sharing asm name: %i\n",
	     node->previous_sharing_asm_name->order);

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

  fprintf (f, "  References: ");
  ipa_dump_references (f, &node->ref_list);
  fprintf (f, "  Referring: ");
  ipa_dump_referring (f, &node->ref_list);
  if (node->lto_file_data)
    fprintf (f, "  Read from file: %s\n",
	     node->lto_file_data->file_name);
}

/* Dump symtab node.  */

void
dump_symtab_node (FILE *f, symtab_node *node)
{
  if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
    dump_cgraph_node (f, cnode);
  else if (varpool_node *vnode = dyn_cast <varpool_node> (node))
    dump_varpool_node (f, vnode);
}

/* Dump symbol table.  */

void
dump_symtab (FILE *f)
{
  symtab_node *node;
  fprintf (f, "Symbol table:\n\n");
  FOR_EACH_SYMBOL (node)
    dump_symtab_node (f, node);
}

/* Dump symtab node NODE to stderr.  */

DEBUG_FUNCTION void
debug_symtab_node (symtab_node *node)
{
  dump_symtab_node (stderr, node);
}

/* Dump symbol table to stderr.  */

DEBUG_FUNCTION void
debug_symtab (void)
{
  dump_symtab (stderr);
}

/* Verify common part of symtab nodes.  */

DEBUG_FUNCTION bool
verify_symtab_base (symtab_node *node)
{
  bool error_found = false;
  symtab_node *hashed_node;

  if (is_a <cgraph_node> (node))
    {
      if (TREE_CODE (node->decl) != FUNCTION_DECL)
	{
          error ("function symbol is not function");
          error_found = true;
	}
    }
  else if (is_a <varpool_node> (node))
    {
      if (TREE_CODE (node->decl) != VAR_DECL)
	{
          error ("variable symbol is not variable");
          error_found = true;
	}
    }
  else
    {
      error ("node has unknown type");
      error_found = true;
    }
   
  if (cgraph_state != CGRAPH_LTO_STREAMING)
    {
      hashed_node = symtab_get_node (node->decl);
      if (!hashed_node)
	{
	  error ("node not found in symtab decl hashtable");
	  error_found = true;
	}
      if (hashed_node != node
	  && (!is_a <cgraph_node> (node)
	      || !dyn_cast <cgraph_node> (node)->clone_of
	      || dyn_cast <cgraph_node> (node)->clone_of->decl
		 != node->decl))
	{
	  error ("node differs from symtab decl hashtable");
	  error_found = true;
	}
    }
  if (assembler_name_hash)
    {
      hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->decl));
      if (hashed_node && hashed_node->previous_sharing_asm_name)
	{
          error ("assembler name hash list corrupted");
          error_found = true;
	}
      while (hashed_node)
	{
	  if (hashed_node == node)
	    break;
	  hashed_node = hashed_node->next_sharing_asm_name;
	}
      if (!hashed_node
          && !(is_a <varpool_node> (node)
	       || DECL_HARD_REGISTER (node->decl)))
	{
          error ("node not found in symtab assembler name hash");
          error_found = true;
	}
    }
  if (node->previous_sharing_asm_name
      && node->previous_sharing_asm_name->next_sharing_asm_name != node)
    {
      error ("double linked list of assembler names corrupted");
      error_found = true;
    }
  if (node->analyzed && !node->definition)
    {
      error ("node is analyzed byt it is not a definition");
      error_found = true;
    }
  if (node->cpp_implicit_alias && !node->alias)
    {
      error ("node is alias but not implicit alias");
      error_found = true;
    }
  if (node->alias && !node->definition
      && !node->weakref)
    {
      error ("node is alias but not definition");
      error_found = true;
    }
  if (node->weakref && !node->alias)
    {
      error ("node is weakref but not an alias");
      error_found = true;
    }
  if (node->same_comdat_group)
    {
      symtab_node *n = node->same_comdat_group;

      if (!DECL_ONE_ONLY (n->decl))
	{
	  error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
	  error_found = true;
	}
      if (DECL_COMDAT_GROUP (n->decl) != DECL_COMDAT_GROUP (node->same_comdat_group->decl))
	{
	  error ("same_comdat_group list across different groups");
	  error_found = true;
	}
      if (!n->definition)
	{
	  error ("Node has same_comdat_group but it is not a definition");
	  error_found = true;
	}
      if (n->type != node->type)
	{
	  error ("mixing different types of symbol in same comdat groups is not supported");
	  error_found = true;
	}
      if (n == node)
	{
	  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 != node);
      if (symtab_comdat_local_p (node))
	{
	  struct ipa_ref_list *refs = &node->ref_list;
	  struct ipa_ref *ref;
	  for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i)
	    {
	      if (!symtab_in_same_comdat_p (ref->referring, node))
		{
		  error ("comdat-local symbol referred to by %s outside its "
			 "comdat",
			 identifier_to_locale (ref->referring->name()));
		  error_found = true;
		}
	    }
	}
    }
  return error_found;
}

/* Verify consistency of NODE.  */

DEBUG_FUNCTION void
verify_symtab_node (symtab_node *node)
{
  if (seen_error ())
    return;

  timevar_push (TV_CGRAPH_VERIFY);
  if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
    verify_cgraph_node (cnode);
  else
    if (verify_symtab_base (node))
      {
        dump_symtab_node (stderr, node);
        internal_error ("verify_symtab_node failed");
      }
  timevar_pop (TV_CGRAPH_VERIFY);
}

/* Verify symbol table for internal consistency.  */

DEBUG_FUNCTION void
verify_symtab (void)
{
  symtab_node *node;
  FOR_EACH_SYMBOL (node)
   verify_symtab_node (node);
}

/* Return true when RESOLUTION indicate that linker will use
   the symbol from non-LTO object files.  */

bool
resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
{
  return (resolution == LDPR_PREVAILING_DEF
          || resolution == LDPR_PREEMPTED_REG
          || resolution == LDPR_RESOLVED_EXEC
          || resolution == LDPR_RESOLVED_DYN);
}

/* Return true when NODE is known to be used from other (non-LTO) object file.
   Known only when doing LTO via linker plugin.  */

bool
symtab_used_from_object_file_p (symtab_node *node)
{
  if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl))
    return false;
  if (resolution_used_from_other_file_p (node->resolution))
    return true;
  return false;
}

/* 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_make_decl_local (tree decl)
{
  rtx rtl, symbol;

  /* Avoid clearing DECL_COMDAT_GROUP on comdat-local decls.  */
  if (TREE_PUBLIC (decl) == 0)
    return;

  if (TREE_CODE (decl) == VAR_DECL)
    DECL_COMMON (decl) = 0;
  else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);

  if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
    {
      DECL_SECTION_NAME (decl) = 0;
      DECL_COMDAT (decl) = 0;
    }
  DECL_COMDAT_GROUP (decl) = 0;
  DECL_WEAK (decl) = 0;
  DECL_EXTERNAL (decl) = 0;
  DECL_VISIBILITY_SPECIFIED (decl) = 0;
  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
  TREE_PUBLIC (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);
}

/* Return availability of NODE.  */

enum availability
symtab_node_availability (symtab_node *node)
{
  if (is_a <cgraph_node> (node))
    return cgraph_function_body_availability (cgraph (node));
  else
    return cgraph_variable_initializer_availability (varpool (node));
}

/* Given NODE, walk the alias chain to return the symbol NODE is alias of.
   If NODE is not an alias, return NODE.
   When AVAILABILITY is non-NULL, get minimal availability in the chain.  */

symtab_node *
symtab_alias_ultimate_target (symtab_node *node, enum availability *availability)
{
  bool weakref_p = false;

  if (!node->alias)
    {
      if (availability)
        *availability = symtab_node_availability (node);
      return node;
    }

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

     Weakref is a different animal (and not part of ELF per se). It is just
     alternative name of a given symbol used within one complation unit
     and is translated prior hitting the object file.  It inherits the
     visibility of its target (i.e. weakref of non-overwritable definition
     is non-overwritable, while weakref of weak definition is weak).

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

  if (availability)
    {
      weakref_p = node->weakref;
      if (!weakref_p)
        *availability = symtab_node_availability (node);
      else
	*availability = AVAIL_LOCAL;
    }
  while (node)
    {
      if (node->alias && node->analyzed)
	node = symtab_alias_target (node);
      else
	{
	  if (!availability)
	    ;
	  else if (node->analyzed)
	    {
	      if (weakref_p)
		{
		  enum availability a = symtab_node_availability (node);
		  if (a < *availability)
		    *availability = a;
		}
	    }
	  else
	    *availability = AVAIL_NOT_AVAILABLE;
	  return node;
	}
      if (node && availability && weakref_p)
	{
	  enum availability a = symtab_node_availability (node);
	  if (a < *availability)
	    *availability = a;
          weakref_p = node->weakref;
	}
    }
  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
fixup_same_cpp_alias_visibility (symtab_node *node, symtab_node *target)
{
  if (is_a <cgraph_node> (node))
    {
      DECL_DECLARED_INLINE_P (node->decl)
	 = DECL_DECLARED_INLINE_P (target->decl);
      DECL_DISREGARD_INLINE_LIMITS (node->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 (node->decl) = DECL_WEAK (target->decl);
      DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl);
      DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (target->decl);
    }
  DECL_VIRTUAL_P (node->decl) = DECL_VIRTUAL_P (target->decl);
  if (TREE_PUBLIC (node->decl))
    {
      DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (target->decl);
      DECL_COMDAT (node->decl) = DECL_COMDAT (target->decl);
      DECL_COMDAT_GROUP (node->decl)
	 = DECL_COMDAT_GROUP (target->decl);
      if (DECL_ONE_ONLY (target->decl)
	  && !node->same_comdat_group)
	symtab_add_to_same_comdat_group (node, target);
    }
  node->externally_visible = target->externally_visible;
}

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

bool
symtab_resolve_alias (symtab_node *node, symtab_node *target)
{
  symtab_node *n;

  gcc_assert (!node->analyzed
	      && !vec_safe_length (node->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 ? symtab_alias_target (n) : NULL)
    if (n == node)
       {
	 if (is_a <cgraph_node> (node))
           error ("function %q+D part of alias cycle", node->decl);
         else if (is_a <varpool_node> (node))
           error ("variable %q+D part of alias cycle", node->decl);
	 else
	   gcc_unreachable ();
	 node->alias = false;
	 return false;
       }

  /* "analyze" the node - i.e. mark the reference.  */
  node->definition = true;
  node->alias = true;
  node->analyzed = true;
  ipa_record_reference (node, target, IPA_REF_ALIAS, NULL);

  /* Alias targets become reudndant 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.  */
  node->alias_target = NULL;

  if (node->cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION)
    fixup_same_cpp_alias_visibility (node, target);

  /* If alias has address taken, so does the target.  */
  if (node->address_taken)
    symtab_alias_ultimate_target (target, NULL)->address_taken = true;
  return true;
}

/* Call calback on NODE and aliases associated to NODE. 
   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
   skipped. */

bool
symtab_for_node_and_aliases (symtab_node *node,
			     bool (*callback) (symtab_node *, void *),
			     void *data,
			     bool include_overwritable)
{
  int i;
  struct ipa_ref *ref;

  if (callback (node, data))
    return true;
  for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      {
	symtab_node *alias = ref->referring;
	if (include_overwritable
	    || symtab_node_availability (alias) > AVAIL_OVERWRITABLE)
          if (symtab_for_node_and_aliases (alias, callback, data,
					   include_overwritable))
	    return true;
      }
  return false;
}

/* Worker searching nonoverwritable alias.  */

static bool
symtab_nonoverwritable_alias_1 (symtab_node *node, void *data)
{
  if (decl_binds_to_current_def_p (node->decl))
    {
      *(symtab_node **)data = node;
      return true;
    }
  return false;
}

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

symtab_node *
symtab_nonoverwritable_alias (symtab_node *node)
{
  tree new_decl;
  symtab_node *new_node = NULL;

  /* First try to look up existing alias or base object
     (if that is already non-overwritable).  */
  node = symtab_alias_ultimate_target (node, NULL);
  gcc_assert (!node->alias && !node->weakref);
  symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
		               (void *)&new_node, true);
  if (new_node)
    return new_node;
#ifndef ASM_OUTPUT_DEF
  /* If aliases aren't supported by the assembler, fail.  */
  return NULL;
#endif

  /* Otherwise create a new one.  */
  new_decl = copy_node (node->decl);
  DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias");
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (new_decl) = NULL;
  DECL_INITIAL (new_decl) = NULL;
  SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
  SET_DECL_RTL (new_decl, NULL);

  /* Update the properties.  */
  DECL_EXTERNAL (new_decl) = 0;
  if (DECL_ONE_ONLY (node->decl))
    DECL_SECTION_NAME (new_decl) = NULL;
  DECL_COMDAT_GROUP (new_decl) = 0;
  TREE_PUBLIC (new_decl) = 0;
  DECL_COMDAT (new_decl) = 0;
  DECL_WEAK (new_decl) = 0;
  DECL_VIRTUAL_P (new_decl) = 0;
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    {
      DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
      DECL_STATIC_DESTRUCTOR (new_decl) = 0;
      new_node = cgraph_create_function_alias
				 (new_decl, node->decl);
    }
  else
    new_node = varpool_create_variable_alias (new_decl,
							    node->decl);
  symtab_resolve_alias (new_node, node);  
  gcc_assert (decl_binds_to_current_def_p (new_decl));
  return new_node;
}

/* Return true if A and B represents semantically equivalent symbols.  */

bool
symtab_semantically_equivalent_p (symtab_node *a,
				  symtab_node *b)
{
  enum availability avail;
  symtab_node *ba;
  symtab_node *bb;

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

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

/* Classify symbol NODE for partitioning.  */

enum symbol_partitioning_class
symtab_get_symbol_partitioning_class (symtab_node *node)
{
  /* Inline clones are always duplicated.
     This include external delcarations.   */
  cgraph_node *cnode = dyn_cast <cgraph_node> (node);

  if (DECL_ABSTRACT (node->decl))
    return SYMBOL_EXTERNAL;

  if (cnode && cnode->global.inlined_to)
    return SYMBOL_DUPLICATE;

  /* Weakref aliases are always duplicated.  */
  if (node->weakref)
    return SYMBOL_DUPLICATE;

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

  if (varpool_node *vnode = dyn_cast <varpool_node> (node))
    {
      /* Constant pool references use local symbol names that can not
         be promoted global.  We should never put into a constant pool
         objects that can not be duplicated across partitions.  */
      if (DECL_IN_CONSTANT_POOL (node->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 (!cgraph (node)->definition)
    return SYMBOL_EXTERNAL;

  /* Linker discardable symbols are duplicated to every use unless they are
     keyed.
     Keyed symbols or those.  */
  if (DECL_ONE_ONLY (node->decl)
      && !node->force_output
      && !node->forced_by_abi
      && !symtab_used_from_object_file_p (node))
    return SYMBOL_DUPLICATE;

  return SYMBOL_PARTITION;
}
#include "gt-symtab.h"
