int nothrow_libfn_p (const_tree fn) { tree id; if (TREE_PUBLIC (fn) && DECL_EXTERNAL (fn) && DECL_NAMESPACE_SCOPE_P (fn) && DECL_EXTERN_C_P (fn)) /* OK */; else /* Can't be a C library function. */ return 0; /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME unless the system headers are playing rename tricks, and if they are, we don't want to be confused by them. */ id = DECL_NAME (fn); const struct libc_name_struct *s = libc_name::libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id)); if (s == NULL) return 0; switch (s->c_ver) { case 89: return 1; case 99: return !flag_iso || flag_isoc99; case 11: return !flag_iso || flag_isoc11; default: gcc_unreachable (); } }
/* 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; }
static void sdbout_toplevel_data (tree decl) { tree type = TREE_TYPE (decl); if (DECL_IGNORED_P (decl)) return; gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (MEM_P (DECL_RTL (decl))); gcc_assert (DECL_INITIAL (decl)); PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); if (TREE_PUBLIC (decl)) { PUT_SDB_SCL (C_EXT); } else { PUT_SDB_SCL (C_STAT); } PUT_SDB_TYPE (plain_type (type)); PUT_SDB_ENDEF; }
static bool lto_symtab_symbol_p (symtab_node *e) { if (!TREE_PUBLIC (e->decl) && !DECL_EXTERNAL (e->decl)) return false; return e->real_symbol_p (); }
/* Mark DECL as finalized. By finalizing the declaration, frontend instruct the middle end to output the variable to asm file, if needed or externally visible. */ void varpool_finalize_decl (tree decl) { struct varpool_node *node = varpool_node (decl); /* The first declaration of a variable that comes through this function decides whether it is global (in C, has external linkage) or local (in C, has internal linkage). So do nothing more if this function has already run. */ if (node->finalized) { if (cgraph_global_info_ready) varpool_assemble_pending_decls (); return; } if (node->needed) varpool_enqueue_needed_node (node); node->finalized = true; if (decide_is_variable_needed (node, decl)) varpool_mark_needed_node (node); /* Since we reclaim unreachable nodes at the end of every language level unit, we need to be conservative about possible entry points there. */ else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) varpool_mark_needed_node (node); if (cgraph_global_info_ready) varpool_assemble_pending_decls (); }
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; }
static inline bool has_proper_scope_for_analysis (tree t) { /* If the variable has the "used" attribute, treat it as if it had a been touched by the devil. */ if (lookup_attribute ("used", DECL_ATTRIBUTES (t))) return false; /* Do not want to do anything with volatile except mark any function that uses one to be not const or pure. */ if (TREE_THIS_VOLATILE (t)) return false; /* Do not care about a local automatic that is not static. */ if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) return false; if (DECL_EXTERNAL (t) || TREE_PUBLIC (t)) return false; /* We cannot touch decls where the type needs constructing. */ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (t))) return false; /* This is a variable we care about. Check if we have seen it before, and if not add it the set of variables we care about. */ if (!bitmap_bit_p (all_module_statics, DECL_UID (t))) add_static_var (t); return true; }
void symtab_node::fixup_same_cpp_alias_visibility (symtab_node *target) { if (is_a <cgraph_node *> (this)) { DECL_DECLARED_INLINE_P (decl) = DECL_DECLARED_INLINE_P (target->decl); DECL_DISREGARD_INLINE_LIMITS (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 (decl) = DECL_WEAK (target->decl); DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl); DECL_VISIBILITY (decl) = DECL_VISIBILITY (target->decl); } DECL_VIRTUAL_P (decl) = DECL_VIRTUAL_P (target->decl); if (TREE_PUBLIC (decl)) { tree group; DECL_EXTERNAL (decl) = DECL_EXTERNAL (target->decl); DECL_COMDAT (decl) = DECL_COMDAT (target->decl); group = target->get_comdat_group (); set_comdat_group (group); if (group && !same_comdat_group) add_to_same_comdat_group (target); } externally_visible = target->externally_visible; }
tree make_alias_for (tree function, tree newid) { tree alias = build_decl (FUNCTION_DECL, newid, TREE_TYPE (function)); DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function); cxx_dup_lang_specific_decl (alias); DECL_CONTEXT (alias) = NULL; TREE_READONLY (alias) = TREE_READONLY (function); TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function); TREE_PUBLIC (alias) = 0; DECL_INTERFACE_KNOWN (alias) = 1; DECL_NOT_REALLY_EXTERN (alias) = 1; DECL_THIS_STATIC (alias) = 1; DECL_SAVED_FUNCTION_DATA (alias) = NULL; DECL_DESTRUCTOR_P (alias) = 0; DECL_CONSTRUCTOR_P (alias) = 0; DECL_CLONED_FUNCTION (alias) = NULL_TREE; DECL_EXTERNAL (alias) = 0; DECL_ARTIFICIAL (alias) = 1; DECL_NO_STATIC_CHAIN (alias) = 1; DECL_PENDING_INLINE_P (alias) = 0; DECL_INLINE (alias) = 0; DECL_DECLARED_INLINE_P (alias) = 0; DECL_DEFERRED_FN (alias) = 0; DECL_USE_TEMPLATE (alias) = 0; DECL_TEMPLATE_INSTANTIATED (alias) = 0; DECL_TEMPLATE_INFO (alias) = NULL; DECL_INITIAL (alias) = error_mark_node; TREE_ADDRESSABLE (alias) = 1; TREE_USED (alias) = 1; SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias)); TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1; return alias; }
static bool i386_pe_determine_dllimport_p (tree decl) { tree assoc; if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return false; if (DECL_DLLIMPORT_P (decl)) return true; /* The DECL_DLLIMPORT_P flag was set for decls in the class definition by targetm.cxx.adjust_class_at_definition. Check again to emit error message if the class attribute has been overridden by an out-of-class definition of static data. */ assoc = associated_type (decl); if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)) && TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl) /* vtable's are linkonce constants, so defining a vtable is not an error as long as we don't try to import it too. */ && !DECL_VIRTUAL_P (decl)) error ("definition of static data member %q+D of " "dllimport%'d class", decl); return false; }
static inline void unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) { /* Note that the code for EXPR has already been unpacked to create EXPR in streamer_alloc_tree. */ if (!TYPE_P (expr)) { TREE_SIDE_EFFECTS (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_CONSTANT (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1); /* TREE_PUBLIC is used on types to indicate that the type has a TYPE_CACHED_VALUES vector. This is not streamed out, so we skip it here. */ TREE_PUBLIC (expr) = (unsigned) bp_unpack_value (bp, 1); } else bp_unpack_value (bp, 4); TREE_ADDRESSABLE (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_THIS_VOLATILE (expr) = (unsigned) bp_unpack_value (bp, 1); if (DECL_P (expr)) DECL_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1); else if (TYPE_P (expr)) TYPE_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1); else bp_unpack_value (bp, 1); TREE_ASM_WRITTEN (expr) = (unsigned) bp_unpack_value (bp, 1); if (TYPE_P (expr)) TYPE_ARTIFICIAL (expr) = (unsigned) bp_unpack_value (bp, 1); else TREE_NO_WARNING (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_NOTHROW (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_STATIC (expr) = (unsigned) bp_unpack_value (bp, 1); if (TREE_CODE (expr) != TREE_BINFO) TREE_PRIVATE (expr) = (unsigned) bp_unpack_value (bp, 1); else bp_unpack_value (bp, 1); TREE_PROTECTED (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1); if (TYPE_P (expr)) { if (AGGREGATE_TYPE_P (expr)) TYPE_REVERSE_STORAGE_ORDER (expr) = (unsigned) bp_unpack_value (bp, 1); else TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_ADDR_SPACE (expr) = (unsigned) bp_unpack_value (bp, 8); } else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF) { REF_REVERSE_STORAGE_ORDER (expr) = (unsigned) bp_unpack_value (bp, 1); bp_unpack_value (bp, 8); } else if (TREE_CODE (expr) == SSA_NAME) { SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1); bp_unpack_value (bp, 8); } else bp_unpack_value (bp, 9); }
static inline void check_decl (funct_state local, tree t, bool checking_write) { /* If the variable has the "used" attribute, treat it as if it had a been touched by the devil. */ if (lookup_attribute ("used", DECL_ATTRIBUTES (t))) { local->pure_const_state = IPA_NEITHER; return; } /* Do not want to do anything with volatile except mark any function that uses one to be not const or pure. */ if (TREE_THIS_VOLATILE (t)) { local->pure_const_state = IPA_NEITHER; return; } /* Do not care about a local automatic that is not static. */ if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) return; /* Since we have dealt with the locals and params cases above, if we are CHECKING_WRITE, this cannot be a pure or constant function. */ if (checking_write) local->pure_const_state = IPA_NEITHER; if (DECL_EXTERNAL (t) || TREE_PUBLIC (t)) { /* If the front end set the variable to be READONLY and constant, we can allow this variable in pure or const functions but the scope is too large for our analysis to set these bits ourselves. */ if (TREE_READONLY (t) && DECL_INITIAL (t) && is_gimple_min_invariant (DECL_INITIAL (t))) ; /* Read of a constant, do not change the function state. */ else { /* Just a regular read. */ if (local->pure_const_state == IPA_CONST) local->pure_const_state = IPA_PURE; } } /* Compilation level statics can be read if they are readonly variables. */ if (TREE_READONLY (t)) return; /* Just a regular read. */ if (local->pure_const_state == IPA_CONST) local->pure_const_state = IPA_PURE; }
void java_mangle_decl (tree decl) { /* A copy of the check from the beginning of lhd_set_decl_assembler_name. */ /* set_decl_assembler_name may be called on TYPE_DECL to record ODR name for C++ types. By default types have no ODR names. */ if (TREE_CODE (decl) == TYPE_DECL) return; /* The language-independent code should never use the DECL_ASSEMBLER_NAME for lots of DECLs. Only FUNCTION_DECLs and VAR_DECLs for variables with static storage duration need a real DECL_ASSEMBLER_NAME. */ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_PUBLIC (decl)))); /* Mangling only applies to class members. */ if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))) { init_mangling (); switch (TREE_CODE (decl)) { case VAR_DECL: if (DECL_LANG_SPECIFIC (decl)) { if (DECL_CLASS_FIELD_P (decl)) { mangle_class_field (decl); break; } else if (DECL_VTABLE_P (decl)) { mangle_vtable (DECL_CONTEXT (decl)); break; } } mangle_field_decl (decl); break; case FUNCTION_DECL: if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl)) mangle_local_cni_method_decl (decl); else mangle_method_decl (decl); break; default: gcc_unreachable (); } SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ()); } else lhd_set_decl_assembler_name (decl); }
/* Set the DECL_ASSEMBLER_NAME for DECL. */ void lhd_set_decl_assembler_name (tree decl) { tree id; /* set_decl_assembler_name may be called on TYPE_DECL to record ODR name for C++ types. By default types have no ODR names. */ if (TREE_CODE (decl) == TYPE_DECL) return; /* The language-independent code should never use the DECL_ASSEMBLER_NAME for lots of DECLs. Only FUNCTION_DECLs and VAR_DECLs for variables with static storage duration need a real DECL_ASSEMBLER_NAME. */ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_PUBLIC (decl)))); /* By default, assume the name to use in assembly code is the same as that used in the source language. (That's correct for C, and GCC used to set DECL_ASSEMBLER_NAME to the same value as DECL_NAME in build_decl, so this choice provides backwards compatibility with existing front-ends. This assumption is wrapped in a target hook, to allow for target-specific modification of the identifier. Can't use just the variable's own name for a variable whose scope is less than the whole compilation. Concatenate a distinguishing number - we use the DECL_UID. */ if (TREE_PUBLIC (decl) || DECL_FILE_SCOPE_P (decl)) id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl)); else { const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); char *label; ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); id = get_identifier (label); } SET_DECL_ASSEMBLER_NAME (decl, id); }
bool symtab_node::used_from_object_file_p_worker (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; }
/* Helper for mudflap_init: construct a decl with the given category, name, and type, mark it an external reference, and pushdecl it. */ static inline tree mf_make_builtin (enum tree_code category, const char *name, tree type) { tree decl = mf_mark (build_decl (category, get_identifier (name), type)); TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; lang_hooks.decls.pushdecl (decl); return decl; }
bool varpool_used_from_object_file_p (struct varpool_node *node) { if (!TREE_PUBLIC (node->decl)) return false; if (resolution_used_from_other_file_p (node->resolution)) return true; return false; }
bool symtab_used_from_object_file_p (symtab_node node) { if (!TREE_PUBLIC (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl)) return false; if (resolution_used_from_other_file_p (node->symbol.resolution)) return true; return false; }
static void i386_pe_mark_dllimport (tree decl) { const char *oldname; char *newname; tree idp; rtx rtlname, newrtl; rtx symref; rtlname = XEXP (DECL_RTL (decl), 0); if (GET_CODE (rtlname) == SYMBOL_REF) oldname = XSTR (rtlname, 0); else if (GET_CODE (rtlname) == MEM && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF) oldname = XSTR (XEXP (rtlname, 0), 0); else abort (); if (i386_pe_dllexport_name_p (oldname)) { error ("%qs declared as both exported to and imported from a DLL", IDENTIFIER_POINTER (DECL_NAME (decl))); return; } else if (i386_pe_dllimport_name_p (oldname)) { /* Already done, but do a sanity check to prevent assembler errors. */ /* APPLE LOCAL begin mainline 2005-10-12 */ if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl) || !DECL_DLLIMPORT_P (decl)) { error ("%Jfailure in redeclaration of '%D': dllimport'd " "symbol lacks external linkage.", decl, decl); abort(); } /* APPLE LOCAL end mainline 2005-10-12 */ return; } newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1); sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname); /* We pass newname through get_identifier to ensure it has a unique address. RTL processing can sometimes peek inside the symbol ref and compare the string's addresses to see if two symbols are identical. */ idp = get_identifier (newname); symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); SYMBOL_REF_DECL (symref) = decl; newrtl = gen_rtx_MEM (Pmode,symref); XEXP (DECL_RTL (decl), 0) = newrtl; /* APPLE LOCAL begin mainline 2005-10-12 */ DECL_DLLIMPORT_P (decl) = 1; /* APPLE LOCAL end mainline 2005-10-12 */ }
/* Add code: __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter __thread void* __gcov_indirect_call_callee; // actual callee address __thread int __gcov_function_counter; // time profiler function counter */ static void init_ic_make_global_vars (void) { tree gcov_type_ptr; ptr_void = build_pointer_type (void_type_node); ic_void_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? "__gcov_indirect_call_topn_callee" : "__gcov_indirect_call_callee")), ptr_void); TREE_PUBLIC (ic_void_ptr_var) = 1; DECL_EXTERNAL (ic_void_ptr_var) = 1; TREE_STATIC (ic_void_ptr_var) = 1; DECL_ARTIFICIAL (ic_void_ptr_var) = 1; DECL_INITIAL (ic_void_ptr_var) = NULL; if (targetm.have_tls) set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var)); varpool_node::finalize_decl (ic_void_ptr_var); gcov_type_ptr = build_pointer_type (get_gcov_type ()); ic_gcov_type_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? "__gcov_indirect_call_topn_counters" : "__gcov_indirect_call_counters")), gcov_type_ptr); TREE_PUBLIC (ic_gcov_type_ptr_var) = 1; DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1; TREE_STATIC (ic_gcov_type_ptr_var) = 1; DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; if (targetm.have_tls) set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var)); varpool_node::finalize_decl (ic_gcov_type_ptr_var); }
static void start_unit_callback (void *gcc_data, void *user_data) { if (integer_type_node) { fake_var = build_decl (VAR_DECL, get_identifier ("_fake_var_"), integer_type_node); TREE_PUBLIC (fake_var) = 1; DECL_ARTIFICIAL (fake_var) = 1; } }
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; DECL_DLLIMPORT_P (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); }
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_DLLIMPORT_P (new_decl) = 0; 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; }
/* Output one variable, if necessary. Return whether we output it. */ bool varpool_assemble_decl (struct varpool_node *node) { tree decl = node->decl; if (!TREE_ASM_WRITTEN (decl) && !node->alias && !node->in_other_partition && !DECL_EXTERNAL (decl) && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) { assemble_variable (decl, 0, 1, 0); if (TREE_ASM_WRITTEN (decl)) { struct varpool_node *alias; node->next_needed = varpool_assembled_nodes_queue; node->prev_needed = NULL; if (varpool_assembled_nodes_queue) varpool_assembled_nodes_queue->prev_needed = node; varpool_assembled_nodes_queue = node; node->finalized = 1; /* Also emit any extra name aliases. */ for (alias = node->extra_name; alias; alias = alias->next) { /* Update linkage fields in case they've changed. */ DECL_WEAK (alias->decl) = DECL_WEAK (decl); TREE_PUBLIC (alias->decl) = TREE_PUBLIC (decl); DECL_VISIBILITY (alias->decl) = DECL_VISIBILITY (decl); assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl)); } 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; 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)) { /* It is possible that we are linking against library defining same COMDAT function. To avoid conflict we need to rename our local name of the function just in the case WHOPR partitioning decide to make it hidden to avoid cross partition references. */ if (flag_wpa) { const char *old_name; symtab_node node = symtab_get_node (decl); old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); change_decl_assembler_name (decl, clone_function_name (decl, "local")); if (node->symbol.lto_file_data) lto_record_renamed_decl (node->symbol.lto_file_data, old_name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); } DECL_SECTION_NAME (decl) = 0; DECL_COMDAT (decl) = 0; } DECL_COMDAT_GROUP (decl) = 0; DECL_WEAK (decl) = 0; DECL_EXTERNAL (decl) = 0; 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); }
/* Add code: static gcov* __gcov_indirect_call_counters; // pointer to actual counter static void* __gcov_indirect_call_callee; // actual callee address */ static void init_ic_make_global_vars (void) { tree gcov_type_ptr; ptr_void = build_pointer_type (void_type_node); ic_void_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ("__gcov_indirect_call_callee"), ptr_void); TREE_STATIC (ic_void_ptr_var) = 1; TREE_PUBLIC (ic_void_ptr_var) = 0; DECL_ARTIFICIAL (ic_void_ptr_var) = 1; DECL_INITIAL (ic_void_ptr_var) = NULL; if (targetm.have_tls) DECL_TLS_MODEL (ic_void_ptr_var) = decl_default_tls_model (ic_void_ptr_var); varpool_finalize_decl (ic_void_ptr_var); varpool_mark_needed_node (varpool_node (ic_void_ptr_var)); gcov_type_ptr = build_pointer_type (get_gcov_type ()); ic_gcov_type_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ("__gcov_indirect_call_counters"), gcov_type_ptr); TREE_STATIC (ic_gcov_type_ptr_var) = 1; TREE_PUBLIC (ic_gcov_type_ptr_var) = 0; DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; if (targetm.have_tls) DECL_TLS_MODEL (ic_gcov_type_ptr_var) = decl_default_tls_model (ic_gcov_type_ptr_var); varpool_finalize_decl (ic_gcov_type_ptr_var); varpool_mark_needed_node (varpool_node (ic_gcov_type_ptr_var)); }
/* Helper for mudflap_init: construct a decl with the given category, name, and type, mark it an external reference, and pushdecl it. */ static inline tree mf_make_builtin (enum tree_code category, const char *name, tree type) { tree decl = mf_mark (build_decl (UNKNOWN_LOCATION, category, get_identifier (name), type)); TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; lang_hooks.decls.pushdecl (decl); /* The decl was declared by the compiler. */ DECL_ARTIFICIAL (decl) = 1; /* And we don't want debug info for it. */ DECL_IGNORED_P (decl) = 1; return decl; }
void java_mangle_decl (tree decl) { /* A copy of the check from the beginning of lhd_set_decl_assembler_name. Only FUNCTION_DECLs and VAR_DECLs for variables with static storage duration need a real DECL_ASSEMBLER_NAME. */ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_PUBLIC (decl)))); /* Mangling only applies to class members. */ if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))) { init_mangling (); switch (TREE_CODE (decl)) { case VAR_DECL: if (DECL_LANG_SPECIFIC (decl)) { if (DECL_CLASS_FIELD_P (decl)) { mangle_class_field (decl); break; } else if (DECL_VTABLE_P (decl)) { mangle_vtable (DECL_CONTEXT (decl)); break; } } mangle_field_decl (decl); break; case FUNCTION_DECL: if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl)) mangle_local_cni_method_decl (decl); else mangle_method_decl (decl); break; default: gcc_unreachable (); } SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ()); } else lhd_set_decl_assembler_name (decl); }
static unsigned int function_and_variable_visibility (void) { struct cgraph_node *node; struct varpool_node *vnode; for (node = cgraph_nodes; node; node = node->next) { if (node->reachable && (DECL_COMDAT (node->decl) || (!flag_whole_program && TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl)))) node->local.externally_visible = true; if (!node->local.externally_visible && node->analyzed && !DECL_EXTERNAL (node->decl)) { gcc_assert (flag_whole_program || !TREE_PUBLIC (node->decl)); TREE_PUBLIC (node->decl) = 0; } node->local.local = (!node->needed && node->analyzed && !DECL_EXTERNAL (node->decl) && !node->local.externally_visible); } for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed) { if (vnode->needed && !flag_whole_program && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))) vnode->externally_visible = 1; if (!vnode->externally_visible) { gcc_assert (flag_whole_program || !TREE_PUBLIC (vnode->decl)); TREE_PUBLIC (vnode->decl) = 0; } /* Static variables defined in auxiliary modules are externalized to allow cross module inlining. */ gcc_assert (TREE_STATIC (vnode->decl) || varpool_is_auxiliary (vnode)); } if (dump_file) { fprintf (dump_file, "\nMarking local functions:"); for (node = cgraph_nodes; node; node = node->next) if (node->local.local) fprintf (dump_file, " %s", cgraph_node_name (node)); fprintf (dump_file, "\n\n"); fprintf (dump_file, "\nMarking externally visible functions:"); for (node = cgraph_nodes; node; node = node->next) if (node->local.externally_visible) fprintf (dump_file, " %s", cgraph_node_name (node)); fprintf (dump_file, "\n\n"); } cgraph_function_flags_ready = true; return 0; }
bool emit_tinfo_decl (tree decl) { tree type = TREE_TYPE (DECL_NAME (decl)); int in_library = typeinfo_in_lib_p (type); tree var_desc, var_init; gcc_assert (DECL_TINFO_P (decl)); if (in_library) { if (doing_runtime) DECL_EXTERNAL (decl) = 0; else { /* If we're not in the runtime, then DECL (which is already DECL_EXTERNAL) will not be defined here. */ DECL_INTERFACE_KNOWN (decl) = 1; return false; } } else if (involves_incomplete_p (type)) { if (!decl_needed_p (decl)) return false; /* If TYPE involves an incomplete class type, then the typeinfo object will be emitted with internal linkage. There is no way to know whether or not types are incomplete until the end of the compilation, so this determination must be deferred until this point. */ TREE_PUBLIC (decl) = 0; DECL_EXTERNAL (decl) = 0; DECL_INTERFACE_KNOWN (decl) = 1; } import_export_decl (decl); if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl)) { DECL_EXTERNAL (decl) = 0; var_desc = get_pseudo_ti_desc (type); var_init = get_pseudo_ti_init (type, var_desc); DECL_INITIAL (decl) = var_init; mark_used (decl); cp_finish_decl (decl, var_init, NULL_TREE, 0); return true; } else return false; }