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