/* Callgraph handling code.
   Copyright (C) 2003-2021 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "timevar.h"
#include "cgraph.h"
#include "lto-streamer.h"
#include "varasm.h"
#include "debug.h"
#include "output.h"
#include "omp-offload.h"
#include "context.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-pass.h"

const char * const tls_model_names[]={"none", "emulated",
				      "global-dynamic", "local-dynamic",
				      "initial-exec", "local-exec"};

/* List of hooks triggered on varpool_node events.  */
struct varpool_node_hook_list {
  varpool_node_hook hook;
  void *data;
  struct varpool_node_hook_list *next;
};

/* Register HOOK to be called with DATA on each removed node.  */
varpool_node_hook_list *
symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
{
  varpool_node_hook_list *entry;
  varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;

  entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
  entry->hook = hook;
  entry->data = data;
  entry->next = NULL;
  while (*ptr)
    ptr = &(*ptr)->next;
  *ptr = entry;
  return entry;
}

/* Remove ENTRY from the list of hooks called on removing nodes.  */
void
symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
{
  varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;

  while (*ptr != entry)
    ptr = &(*ptr)->next;
  *ptr = entry->next;
  free (entry);
}

/* Call all node removal hooks.  */
void
symbol_table::call_varpool_removal_hooks (varpool_node *node)
{
  varpool_node_hook_list *entry = m_first_varpool_removal_hook;
  while (entry)
  {
    entry->hook (node, entry->data);
    entry = entry->next;
  }
}

/* Register HOOK to be called with DATA on each inserted node.  */
varpool_node_hook_list *
symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data)
{
  varpool_node_hook_list *entry;
  varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;

  entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
  entry->hook = hook;
  entry->data = data;
  entry->next = NULL;
  while (*ptr)
    ptr = &(*ptr)->next;
  *ptr = entry;
  return entry;
}

/* Remove ENTRY from the list of hooks called on inserted nodes.  */
void
symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry)
{
  varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;

  while (*ptr != entry)
    ptr = &(*ptr)->next;
  *ptr = entry->next;
  free (entry);
}

/* Call all node insertion hooks.  */
void
symbol_table::call_varpool_insertion_hooks (varpool_node *node)
{
  varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
  while (entry)
  {
    entry->hook (node, entry->data);
    entry = entry->next;
  }
}

/* Allocate new callgraph node and insert it into basic data structures.  */

varpool_node *
varpool_node::create_empty (void)
{
  return new (ggc_alloc<varpool_node> ()) varpool_node ();
}   

/* Return varpool node assigned to DECL.  Create new one when needed.  */
varpool_node *
varpool_node::get_create (tree decl)
{
  varpool_node *node = varpool_node::get (decl);
  gcc_checking_assert (VAR_P (decl));
  if (node)
    return node;

  node = varpool_node::create_empty ();
  node->decl = decl;

  if ((flag_openacc || flag_openmp)
      && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
    {
      node->offloadable = 1;
      if (ENABLE_OFFLOADING && !DECL_EXTERNAL (decl))
	{
	  g->have_offload = true;
	  if (!in_lto_p)
	    vec_safe_push (offload_vars, decl);
	}
    }

  node->register_symbol ();
  return node;
}

/* Remove variable from symbol table.  */

void
varpool_node::remove (void)
{
  symtab->call_varpool_removal_hooks (this);
  if (lto_file_data)
    {
      lto_free_function_in_decl_state_for_node (this);
      lto_file_data = NULL;
    }

  /* When streaming we can have multiple nodes associated with decl.  */
  if (symtab->state == LTO_STREAMING)
    ;
  /* Keep constructor when it may be used for folding. We remove
     references to external variables before final compilation.  */
  else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
	   && !ctor_useable_for_folding_p ())
    remove_initializer ();

  unregister (NULL);
  ggc_free (this);
}

/* Remove node initializer when it is no longer needed.  */
void
varpool_node::remove_initializer (void)
{
  if (DECL_INITIAL (decl)
      && !DECL_IN_CONSTANT_POOL (decl)
      /* Keep vtables for BINFO folding.  */
      && !DECL_VIRTUAL_P (decl)
      /* FIXME: http://gcc.gnu.org/PR55395 */
      && debug_info_level == DINFO_LEVEL_NONE
      /* When doing declaration merging we have duplicate
	 entries for given decl.  Do not attempt to remove
	 the bodies, or we will end up removing
	 wrong one.  */
      && symtab->state != LTO_STREAMING)
    DECL_INITIAL (decl) = error_mark_node;
}

/* Dump given varpool node to F.  */
void
varpool_node::dump (FILE *f)
{
  dump_base (f);
  fprintf (f, "  Availability: %s\n",
	   symtab->function_flags_ready
	   ? cgraph_availability_names[get_availability ()]
	   : "not-ready");
  fprintf (f, "  Varpool flags:");
  if (DECL_INITIAL (decl))
    fprintf (f, " initialized");
  if (output)
    fprintf (f, " output");
  if (used_by_single_function)
    fprintf (f, " used-by-single-function");
  if (TREE_READONLY (decl))
    fprintf (f, " read-only");
  if (ctor_useable_for_folding_p ())
    fprintf (f, " const-value-known");
  if (writeonly)
    fprintf (f, " write-only");
  if (tls_model)
    fprintf (f, " tls-%s", tls_model_names [tls_model]);
  fprintf (f, "\n");
}


/* Dump given varpool node to stderr.  */
void varpool_node::debug (void)
{
  varpool_node::dump (stderr);
}

/* Dump the variable pool to F.  */
void
varpool_node::dump_varpool (FILE *f)
{
  varpool_node *node;

  fprintf (f, "variable pool:\n\n");
  FOR_EACH_VARIABLE (node)
    node->dump (f);
}

/* Dump the variable pool to stderr.  */

DEBUG_FUNCTION void
varpool_node::debug_varpool (void)
{
  dump_varpool (stderr);
}

/* Given an assembler name, lookup node.  */
varpool_node *
varpool_node::get_for_asmname (tree asmname)
{
  if (symtab_node *node = symtab_node::get_for_asmname (asmname))
    return dyn_cast <varpool_node *> (node);
  else
    return NULL;
}

/* When doing LTO, read variable's constructor from disk if
   it is not already present.  */

tree
varpool_node::get_constructor (void)
{
  lto_file_decl_data *file_data;
  const char *data, *name;
  size_t len;

  if (DECL_INITIAL (decl) != error_mark_node
      || !in_lto_p
      || !lto_file_data)
    return DECL_INITIAL (decl);

  timevar_push (TV_IPA_LTO_CTORS_IN);

  file_data = lto_file_data;
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));

  /* We may have renamed the declaration, e.g., a static function.  */
  name = lto_get_decl_name_mapping (file_data, name);
  struct lto_in_decl_state *decl_state
	 = lto_get_function_in_decl_state (file_data, decl);

  data = lto_get_section_data (file_data, LTO_section_function_body,
			       name, order - file_data->order_base,
			       &len, decl_state->compressed);
  if (!data)
    fatal_error (input_location, "%s: section %s.%d is missing",
		 file_data->file_name,
		 name, order - file_data->order_base);

  if (!quiet_flag)
    fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
  lto_input_variable_constructor (file_data, this, data);
  gcc_assert (DECL_INITIAL (decl) != error_mark_node);
  lto_stats.num_function_bodies++;
  lto_free_section_data (file_data, LTO_section_function_body, name,
			 data, len, decl_state->compressed);
  lto_free_function_in_decl_state_for_node (this);
  timevar_pop (TV_IPA_LTO_CTORS_IN);
  return DECL_INITIAL (decl);
}

/* Return true if variable has constructor that can be used for folding.  */

bool
varpool_node::ctor_useable_for_folding_p (void)
{
  varpool_node *real_node = this;

  if (real_node->alias && real_node->definition)
    real_node = ultimate_alias_target ();

  if (TREE_CODE (decl) == CONST_DECL
      || DECL_IN_CONSTANT_POOL (decl))
    return true;
  if (TREE_THIS_VOLATILE (decl))
    return false;

  /* Avoid attempts to load constructors that was not streamed.  */
  if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
      && real_node->body_removed)
    return false;

  /* If we do not have a constructor, we can't use it.  */
  if (DECL_INITIAL (real_node->decl) == error_mark_node
      && !real_node->lto_file_data)
    return false;

  /* Vtables are defined by their types and must match no matter of interposition
     rules.  */
  if (DECL_VIRTUAL_P (decl))
    {
      /* The C++ front end creates VAR_DECLs for vtables of typeinfo
	 classes not defined in the current TU so that it can refer
	 to them from typeinfo objects.  Avoid returning NULL_TREE.  */
      return DECL_INITIAL (real_node->decl) != NULL;
    }

  /* An alias of a read-only variable is also read-only, since the variable
     is stored in read-only memory.  We also accept read-only aliases of
     non-read-only locations assuming that the user knows what he is asking
     for.  */
  if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl))
    return false;

  /* Variables declared 'const' without an initializer
     have zero as the initializer if they may not be
     overridden at link or run time.

     It is actually requirement for C++ compiler to optimize const variables
     consistently. As a GNU extension, do not enforce this rule for user defined
     weak variables, so we support interposition on:
     static const int dummy = 0;
     extern const int foo __attribute__((__weak__, __alias__("dummy"))); 
   */
  if ((!DECL_INITIAL (real_node->decl)
       || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
      && (DECL_EXTERNAL (decl) || decl_replaceable_p (decl)))
    return false;

  /* Variables declared `const' with an initializer are considered
     to not be overwritable with different initializer by default. 

     ??? Previously we behaved so for scalar variables but not for array
     accesses.  */
  return true;
}

/* If DECLARATION is constant variable and its initial value is known
   (so we can do constant folding), return its constructor (DECL_INITIAL).
   This may be an expression or NULL when DECL is initialized to 0.
   Return ERROR_MARK_NODE otherwise.

   In LTO this may actually trigger reading the constructor from disk.
   For this reason varpool_ctor_useable_for_folding_p should be used when
   the actual constructor value is not needed.  */

tree
ctor_for_folding (tree decl)
{
  varpool_node *node, *real_node;
  tree real_decl;

  if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
    return error_mark_node;

  if (TREE_CODE (decl) == CONST_DECL
      || DECL_IN_CONSTANT_POOL (decl))
    return DECL_INITIAL (decl);

  if (TREE_THIS_VOLATILE (decl))
    return error_mark_node;

  /* Do not care about automatic variables.  Those are never initialized
     anyway, because gimplifier expands the code.  */
  if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
    {
      gcc_assert (!TREE_PUBLIC (decl));
      /* Unless this is called during FE folding.  */
      if (cfun
	  && (cfun->curr_properties & (PROP_gimple | PROP_rtl)) == 0
	  && TREE_READONLY (decl)
	  && !TREE_SIDE_EFFECTS (decl)
	  && DECL_INITIAL (decl))
	return DECL_INITIAL (decl);
      return error_mark_node;
    }

  gcc_assert (VAR_P (decl));

  real_node = node = varpool_node::get (decl);
  if (node)
    {
      real_node = node->ultimate_alias_target ();
      real_decl = real_node->decl;
    }
  else
    real_decl = decl;

  /* See if we are dealing with alias.
     In most cases alias is just alternative symbol pointing to a given
     constructor.  This allows us to use interposition rules of DECL
     constructor of REAL_NODE.  However weakrefs are special by being just
     alternative name of their target (if defined).  */
  if (decl != real_decl)
    {
      gcc_assert (!DECL_INITIAL (decl)
		  || (node->alias && node->get_alias_target () == real_node)
		  || DECL_INITIAL (decl) == error_mark_node);
      while (node->transparent_alias && node->analyzed)
	{
	  node = node->get_alias_target ();
	  decl = node->decl;
	}
    }

  if ((!DECL_VIRTUAL_P (real_decl)
       || DECL_INITIAL (real_decl) == error_mark_node
       || !DECL_INITIAL (real_decl))
      && (!node || !node->ctor_useable_for_folding_p ()))
    return error_mark_node;

  /* OK, we can return constructor.  See if we need to fetch it from disk
     in LTO mode.  */
  if (DECL_INITIAL (real_decl) != error_mark_node
      || !in_lto_p)
    return DECL_INITIAL (real_decl);
  return real_node->get_constructor ();
}

/* Add the variable DECL to the varpool.
   Unlike finalize_decl function is intended to be used
   by middle end and allows insertion of new variable at arbitrary point
   of compilation.  */
void
varpool_node::add (tree decl)
{
  varpool_node *node;
  varpool_node::finalize_decl (decl);
  node = varpool_node::get_create (decl);
  symtab->call_varpool_insertion_hooks (node);
  if (node->externally_visible_p ())
    node->externally_visible = true;
  if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
    node->no_reorder = 1;
}

/* Return variable availability.  See cgraph.h for description of individual
   return values.  */
enum availability
varpool_node::get_availability (symtab_node *ref)
{
  if (!definition && !in_other_partition)
    return AVAIL_NOT_AVAILABLE;
  if (!TREE_PUBLIC (decl))
    return AVAIL_AVAILABLE;
  if (DECL_IN_CONSTANT_POOL (decl)
      || DECL_VIRTUAL_P (decl))
    return AVAIL_AVAILABLE;
  if (transparent_alias && definition)
    {
      enum availability avail;

      ultimate_alias_target (&avail, ref);
      return avail;
    }
  /* 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.  */
  if ((this == ref && !has_aliases_p ())
      || (ref && get_comdat_group ()
          && get_comdat_group () == ref->get_comdat_group ()))
    return AVAIL_AVAILABLE;
  /* If the variable can be overwritten, return OVERWRITABLE.  Takes
     care of at least one notable extension - the COMDAT variables
     used to share template instantiations in C++.  */
  if (decl_replaceable_p (decl)
      || DECL_EXTERNAL (decl))
    return AVAIL_INTERPOSABLE;
  return AVAIL_AVAILABLE;
}

void
varpool_node::analyze (void)
{
  /* When reading back varpool at LTO time, we re-construct the queue in order
     to have "needed" list right by inserting all needed nodes into varpool.
     We however don't want to re-analyze already analyzed nodes.  */
  if (!analyzed)
    {
      gcc_assert (!in_lto_p || symtab->function_flags_ready);
      /* Compute the alignment early so function body expanders are
	 already informed about increased alignment.  */
      align_variable (decl, 0);
    }
  if (alias)
    resolve_alias (varpool_node::get (alias_target));
  else if (DECL_INITIAL (decl))
    record_references_in_initializer (decl, analyzed);
  analyzed = true;
}

/* Assemble thunks and aliases associated to varpool node.  */

void
varpool_node::assemble_aliases (void)
{
  ipa_ref *ref;

  FOR_EACH_ALIAS (this, ref)
    {
      varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
      if (alias->symver)
	do_assemble_symver (alias->decl,
			    DECL_ASSEMBLER_NAME (decl));
      else if (!alias->transparent_alias)
	do_assemble_alias (alias->decl,
			   DECL_ASSEMBLER_NAME (decl));
      alias->assemble_aliases ();
    }
}

/* Output one variable, if necessary.  Return whether we output it.  */

bool
varpool_node::assemble_decl (void)
{
  /* Aliases are output when their target is produced or by
     output_weakrefs.  */
  if (alias)
    return false;

  /* Constant pool is output from RTL land when the reference
     survive till this level.  */
  if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
    return false;

  /* Decls with VALUE_EXPR should not be in the varpool at all.  They
     are not real variables, but just info for debugging and codegen.
     Unfortunately at the moment emutls is not updating varpool correctly
     after turning real vars into value_expr vars.  */
  if (DECL_HAS_VALUE_EXPR_P (decl)
      && !targetm.have_tls)
    return false;

  /* Hard register vars do not need to be output.  */
  if (DECL_HARD_REGISTER (decl))
    return false;

  gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
		       && VAR_P (decl)
		       && !DECL_HAS_VALUE_EXPR_P (decl));

  if (!in_other_partition
      && !DECL_EXTERNAL (decl))
    {
      get_constructor ();
      assemble_variable (decl, 0, 1, 0);
      gcc_assert (TREE_ASM_WRITTEN (decl));
      gcc_assert (definition);
      assemble_aliases ();
      /* After the parser has generated debugging information, augment
	 this information with any new location/etc information that may
	 have become available after the compilation proper.  */
      debug_hooks->late_global_decl (decl);
      return true;
    }

  return false;
}

/* Add NODE to queue starting at FIRST. 
   The queue is linked via AUX pointers and terminated by pointer to 1.  */

static void
enqueue_node (varpool_node *node, varpool_node **first)
{
  if (node->aux)
    return;
  gcc_checking_assert (*first);
  node->aux = *first;
  *first = node;
}

/* Optimization of function bodies might've rendered some variables as
   unnecessary so we want to avoid these from being compiled.  Re-do
   reachability starting from variables that are either externally visible
   or was referred from the asm output routines.  */

void
symbol_table::remove_unreferenced_decls (void)
{
  varpool_node *next, *node;
  varpool_node *first = (varpool_node *)(void *)1;
  int i;
  ipa_ref *ref = NULL;
  hash_set<varpool_node *> referenced;

  if (seen_error ())
    return;

  if (dump_file)
    fprintf (dump_file, "Trivially needed variables:");
  FOR_EACH_DEFINED_VARIABLE (node)
    {
      if (node->analyzed
	  && (!node->can_remove_if_no_refs_p ()
	      /* We just expanded all function bodies.  See if any of
		 them needed the variable.  */
	      || DECL_RTL_SET_P (node->decl)))
	{
	  enqueue_node (node, &first);
	  if (dump_file)
	    fprintf (dump_file, " %s", node->dump_asm_name ());
	}
    }
  while (first != (varpool_node *)(void *)1)
    {
      node = first;
      first = (varpool_node *)first->aux;

      if (node->same_comdat_group)
	{
	  symtab_node *next;
	  for (next = node->same_comdat_group;
	       next != node;
	       next = next->same_comdat_group)
	    {
	      varpool_node *vnext = dyn_cast <varpool_node *> (next);
	      if (vnext && vnext->analyzed && !next->comdat_local_p ())
		enqueue_node (vnext, &first);
	    }
	}
      for (i = 0; node->iterate_reference (i, ref); i++)
	{
	  varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
	  if (vnode
	      && !vnode->in_other_partition
	      && (!DECL_EXTERNAL (ref->referred->decl)
		  || vnode->alias)
	      && vnode->analyzed)
	    enqueue_node (vnode, &first);
	  else
	    {
	      referenced.add (vnode);
	      while (vnode && vnode->alias && vnode->definition)
		{
		  vnode = vnode->get_alias_target ();
	          referenced.add (vnode);
		}
	    }
	}
    }
  if (dump_file)
    fprintf (dump_file, "\nRemoving variables:");
  for (node = first_defined_variable (); node; node = next)
    {
      next = next_defined_variable (node);
      if (!node->aux && !node->no_reorder)
	{
	  if (dump_file)
	    fprintf (dump_file, " %s", node->dump_asm_name ());
	  if (referenced.contains(node))
	    node->remove_initializer ();
	  else
	    node->remove ();
	}
    }

  if (dump_file)
    fprintf (dump_file, "\n");
}

/* For variables in named sections make sure get_variable_section
   is called before we switch to those sections.  Then section
   conflicts between read-only and read-only requiring relocations
   sections can be resolved.  */
void
varpool_node::finalize_named_section_flags (void)
{
  if (!TREE_ASM_WRITTEN (decl)
      && !alias
      && !in_other_partition
      && !DECL_EXTERNAL (decl)
      && VAR_P (decl)
      && !DECL_HAS_VALUE_EXPR_P (decl)
      && get_section ())
    get_variable_section (decl, false);
}

/* Output all variables enqueued to be assembled.  */
bool
symbol_table::output_variables (void)
{
  bool changed = false;
  varpool_node *node;

  if (seen_error ())
    return false;

  remove_unreferenced_decls ();

  timevar_push (TV_VAROUT);

  FOR_EACH_DEFINED_VARIABLE (node)
    {
      /* Handled in output_in_order.  */
      if (node->no_reorder)
	continue;

      node->finalize_named_section_flags ();
    }

  /* There is a similar loop in output_in_order.  Please keep them in sync.  */
  FOR_EACH_VARIABLE (node)
    {
      /* Handled in output_in_order.  */
      if (node->no_reorder)
	continue;
      if (DECL_HARD_REGISTER (node->decl)
	  || DECL_HAS_VALUE_EXPR_P (node->decl))
	continue;
      if (node->definition)
	changed |= node->assemble_decl ();
      else
	assemble_undefined_decl (node->decl);
    }
  timevar_pop (TV_VAROUT);
  return changed;
}

/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
   Extra name aliases are output whenever DECL is output.  */

varpool_node *
varpool_node::create_alias (tree alias, tree decl)
{
  varpool_node *alias_node;

  gcc_assert (VAR_P (decl));
  gcc_assert (VAR_P (alias));
  alias_node = varpool_node::get_create (alias);
  alias_node->alias = true;
  alias_node->definition = true;
  alias_node->alias_target = decl;
  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
    alias_node->weakref = alias_node->transparent_alias = true;
  return alias_node;
}

/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
   Extra name aliases are output whenever DECL is output.  */

varpool_node *
varpool_node::create_extra_name_alias (tree alias, tree decl)
{
  varpool_node *alias_node;

  /* If aliases aren't supported by the assembler, fail.  */
  if (!TARGET_SUPPORTS_ALIASES)
    return NULL;

  alias_node = varpool_node::create_alias (alias, decl);
  alias_node->cpp_implicit_alias = true;

  /* Extra name alias mechanism creates aliases really late
     via DECL_ASSEMBLER_NAME mechanism.
     This is unfortunate because they are not going through the
     standard channels.  Ensure they get output.  */
  if (symtab->cpp_implicit_aliases_done)
    alias_node->resolve_alias (varpool_node::get_create (decl));
  return alias_node;
}

/* Worker for call_for_symbol_and_aliases.  */

bool
varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
							       void *),
					     void *data,
					     bool include_overwritable)
{
  ipa_ref *ref;

  FOR_EACH_ALIAS (this, ref)
    {
      varpool_node *alias = dyn_cast <varpool_node *> (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;
}
