Beispiel #1
0
/* Return variable availability.  See cgraph.h for description of individual
   return values.  */
enum availability
cgraph_variable_initializer_availability (varpool_node *node)
{
  if (!node->definition)
    return AVAIL_NOT_AVAILABLE;
  if (!TREE_PUBLIC (node->decl))
    return AVAIL_AVAILABLE;
  if (DECL_IN_CONSTANT_POOL (node->decl)
      || DECL_VIRTUAL_P (node->decl))
    return AVAIL_AVAILABLE;
  if (node->alias && node->weakref)
    {
      enum availability avail;

      cgraph_variable_initializer_availability
	      (varpool_variable_node (node, &avail));
      return avail;
    }
  /* 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 (node->decl)
      || DECL_EXTERNAL (node->decl))
    return AVAIL_OVERWRITABLE;
  return AVAIL_AVAILABLE;
}
Beispiel #2
0
/* Return variable availability.  See cgraph.h for description of individual
   return values.  */
enum availability
cgraph_variable_initializer_availability (struct varpool_node *node)
{
  gcc_assert (cgraph_function_flags_ready);
  if (!node->finalized)
    return AVAIL_NOT_AVAILABLE;
  if (!TREE_PUBLIC (node->decl))
    return AVAIL_AVAILABLE;
  /* If the variable can be overwritten, return OVERWRITABLE.  Takes
     care of at least two notable extensions - the COMDAT variables
     used to share template instantiations in C++.  */
  if (!decl_replaceable_p (node->decl))
    return AVAIL_OVERWRITABLE;
  return AVAIL_AVAILABLE;
}
Beispiel #3
0
bool
const_value_known_p (tree decl)
{
  if (TREE_CODE (decl) != VAR_DECL
      &&TREE_CODE (decl) != CONST_DECL)
    return false;

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

  gcc_assert (TREE_CODE (decl) == VAR_DECL);

  if (!TREE_READONLY (decl) || TREE_THIS_VOLATILE (decl))
    return false;

  /* Gimplifier takes away constructors of local vars  */
  if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
    return DECL_INITIAL (decl) != NULL;

  gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));

  /* Variables declared 'const' without an initializer
     have zero as the initializer if they may not be
     overridden at link or run time.  */
  if (!DECL_INITIAL (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;
}
Beispiel #4
0
tree
ctor_for_folding (tree decl)
{
  varpool_node *node, *real_node;
  tree real_decl;

  if (TREE_CODE (decl) != VAR_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 exapnds the code.  */
  if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
    {
      gcc_assert (!TREE_PUBLIC (decl));
      return error_mark_node;
    }

  gcc_assert (TREE_CODE (decl) == VAR_DECL);

  node = varpool_get_node (decl);
  if (node)
    {
      real_node = varpool_variable_node (node);
      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)
		  || DECL_INITIAL (decl) == error_mark_node);
      if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
	{
	  node = varpool_alias_target (node);
	  decl = node->decl;
	}
    }

  /* Vtables are defined by their types and must match no matter of interposition
     rules.  */
  if (DECL_VIRTUAL_P (real_decl))
    {
      gcc_checking_assert (TREE_READONLY (real_decl));
      return DECL_INITIAL (real_decl);
    }

  /* If there is no constructor, we have nothing to do.  */
  if (DECL_INITIAL (real_decl) == error_mark_node)
    return error_mark_node;

  /* Non-readonly alias of readonly variable is also de-facto readonly,
     because the variable itself is in readonly section.  
     We also honnor READONLY flag on alias assuming that user knows
     what he is doing.  */
  if (!TREE_READONLY (decl) && !TREE_READONLY (real_decl))
    return error_mark_node;

  /* Variables declared 'const' without an initializer
     have zero as the initializer if they may not be
     overridden at link or run time.  */
  if (!DECL_INITIAL (real_decl)
      && (DECL_EXTERNAL (decl) || decl_replaceable_p (decl)))
    return error_mark_node;

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