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

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "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) && !in_other_partition)
	  || decl_replaceable_p (decl, semantic_interposition)))
    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, semantic_interposition)
      || (DECL_EXTERNAL (decl) && !in_other_partition))
    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->semantic_interposition = flag_semantic_interposition;
  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;
}
