/* 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 unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { DECL_DEFER_OUTPUT (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_COMMON (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_DLLIMPORT_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_WEAK (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_SEEN_IN_BIND_EXPR_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_COMDAT (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_VISIBILITY (expr) = (enum symbol_visibility) bp_unpack_value (bp, 2); DECL_VISIBILITY_SPECIFIED (expr) = (unsigned) bp_unpack_value (bp, 1); if (TREE_CODE (expr) == VAR_DECL) { DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3); } if (VAR_OR_FUNCTION_DECL_P (expr)) { priority_type p; p = (priority_type) bp_unpack_var_len_unsigned (bp); SET_DECL_INIT_PRIORITY (expr, p); } }
static void pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { bp_pack_value (bp, DECL_COMMON (expr), 1); bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1); bp_pack_value (bp, DECL_WEAK (expr), 1); bp_pack_value (bp, DECL_SEEN_IN_BIND_EXPR_P (expr), 1); bp_pack_value (bp, DECL_COMDAT (expr), 1); bp_pack_value (bp, DECL_VISIBILITY (expr), 2); bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr), 1); if (TREE_CODE (expr) == VAR_DECL) { bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1); /* DECL_IN_TEXT_SECTION is set during final asm output only. */ bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1); } if (TREE_CODE (expr) == FUNCTION_DECL) { bp_pack_value (bp, DECL_FINAL_P (expr), 1); bp_pack_value (bp, DECL_CXX_CONSTRUCTOR_P (expr), 1); bp_pack_value (bp, DECL_CXX_DESTRUCTOR_P (expr), 1); } }
/* Remove node from the varpool. */ void varpool_remove_node (struct varpool_node *node) { symtab_unregister_node ((symtab_node)node); if (DECL_INITIAL (node->symbol.decl) && !DECL_IN_CONSTANT_POOL (node->symbol.decl) /* Keep vtables for BINFO folding. */ && !DECL_VIRTUAL_P (node->symbol.decl) /* FIXME: http://gcc.gnu.org/PR55395 */ && debug_info_level == DINFO_LEVEL_NONE) DECL_INITIAL (node->symbol.decl) = error_mark_node; ggc_free (node); }
enum symbol_partitioning_class symtab_get_symbol_partitioning_class (symtab_node *node) { /* Inline clones are always duplicated. This include external delcarations. */ cgraph_node *cnode = dyn_cast <cgraph_node> (node); if (DECL_ABSTRACT (node->decl)) return SYMBOL_EXTERNAL; if (cnode && cnode->global.inlined_to) return SYMBOL_DUPLICATE; /* Weakref aliases are always duplicated. */ if (node->weakref) return SYMBOL_DUPLICATE; /* External declarations are external. */ if (DECL_EXTERNAL (node->decl)) return SYMBOL_EXTERNAL; if (varpool_node *vnode = dyn_cast <varpool_node> (node)) { /* Constant pool references use local symbol names that can not be promoted global. We should never put into a constant pool objects that can not be duplicated across partitions. */ if (DECL_IN_CONSTANT_POOL (node->decl)) return SYMBOL_DUPLICATE; gcc_checking_assert (vnode->definition); } /* Functions that are cloned may stay in callgraph even if they are unused. Handle them as external; compute_ltrans_boundary take care to make proper things to happen (i.e. to make them appear in the boundary but with body streamed, so clone can me materialized). */ else if (!cgraph (node)->definition) return SYMBOL_EXTERNAL; /* Linker discardable symbols are duplicated to every use unless they are keyed. Keyed symbols or those. */ if (DECL_ONE_ONLY (node->decl) && !node->force_output && !node->forced_by_abi && !symtab_used_from_object_file_p (node)) return SYMBOL_DUPLICATE; return SYMBOL_PARTITION; }
/* Renove node initializer when it is no longer needed. */ void varpool_remove_initializer (varpool_node *node) { if (DECL_INITIAL (node->decl) && !DECL_IN_CONSTANT_POOL (node->decl) /* Keep vtables for BINFO folding. */ && !DECL_VIRTUAL_P (node->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 boides, or we will end up remiving wrong one. */ && cgraph_state != CGRAPH_LTO_STREAMING) DECL_INITIAL (node->decl) = error_mark_node; }
bool varpool_assemble_decl (varpool_node *node) { tree decl = node->decl; /* Aliases are outout when their target is produced or by output_weakrefs. */ if (node->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) && TREE_CODE (decl) == VAR_DECL && !DECL_HAS_VALUE_EXPR_P (decl)); if (!node->in_other_partition && !DECL_EXTERNAL (decl)) { assemble_variable (decl, 0, 1, 0); gcc_assert (TREE_ASM_WRITTEN (decl)); node->definition = true; assemble_aliases (node); return true; } return false; }
static void pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { bp_pack_value (bp, DECL_DEFER_OUTPUT (expr), 1); bp_pack_value (bp, DECL_COMMON (expr), 1); bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1); bp_pack_value (bp, DECL_WEAK (expr), 1); bp_pack_value (bp, DECL_SEEN_IN_BIND_EXPR_P (expr), 1); bp_pack_value (bp, DECL_COMDAT (expr), 1); bp_pack_value (bp, DECL_VISIBILITY (expr), 2); bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr), 1); if (TREE_CODE (expr) == VAR_DECL) { bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1); bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1); bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1); bp_pack_value (bp, DECL_TLS_MODEL (expr), 3); } if (VAR_OR_FUNCTION_DECL_P (expr)) bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr)); }
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; }
static void unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { DECL_COMMON (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_DLLIMPORT_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_WEAK (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_SEEN_IN_BIND_EXPR_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_COMDAT (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_VISIBILITY (expr) = (enum symbol_visibility) bp_unpack_value (bp, 2); DECL_VISIBILITY_SPECIFIED (expr) = (unsigned) bp_unpack_value (bp, 1); if (TREE_CODE (expr) == VAR_DECL) { DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1); } if (TREE_CODE (expr) == FUNCTION_DECL) { DECL_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_CXX_CONSTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_CXX_DESTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1); } }
void print_node (FILE *file, const char *prefix, tree node, int indent) { int hash; struct bucket *b; machine_mode mode; enum tree_code_class tclass; int len; int i; expanded_location xloc; enum tree_code code; if (node == 0) return; code = TREE_CODE (node); tclass = TREE_CODE_CLASS (code); /* Don't get too deep in nesting. If the user wants to see deeper, it is easy to use the address of a lowest-level node as an argument in another call to debug_tree. */ if (indent > 24) { print_node_brief (file, prefix, node, indent); return; } if (indent > 8 && (tclass == tcc_type || tclass == tcc_declaration)) { print_node_brief (file, prefix, node, indent); return; } /* It is unsafe to look at any other fields of an ERROR_MARK node. */ if (code == ERROR_MARK) { print_node_brief (file, prefix, node, indent); return; } /* Allow this function to be called if the table is not there. */ if (table) { hash = ((uintptr_t) node) % HASH_SIZE; /* If node is in the table, just mention its address. */ for (b = table[hash]; b; b = b->next) if (b->node == node) { print_node_brief (file, prefix, node, indent); return; } /* Add this node to the table. */ b = XNEW (struct bucket); b->node = node; b->next = table[hash]; table[hash] = b; } /* Indent to the specified column, since this is the long form. */ indent_to (file, indent); /* Print the slot this node is in, and its code, and address. */ fprintf (file, "%s <%s", prefix, get_tree_code_name (code)); dump_addr (file, " ", node); /* Print the name, if any. */ if (tclass == tcc_declaration) { if (DECL_NAME (node)) fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node))); else if (code == LABEL_DECL && LABEL_DECL_UID (node) != -1) { if (dump_flags & TDF_NOUID) fprintf (file, " L.xxxx"); else fprintf (file, " L.%d", (int) LABEL_DECL_UID (node)); } else { if (dump_flags & TDF_NOUID) fprintf (file, " %c.xxxx", code == CONST_DECL ? 'C' : 'D'); else fprintf (file, " %c.%u", code == CONST_DECL ? 'C' : 'D', DECL_UID (node)); } } else if (tclass == tcc_type) { if (TYPE_NAME (node)) { if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node))); else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL && DECL_NAME (TYPE_NAME (node))) fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)))); } } if (code == IDENTIFIER_NODE) fprintf (file, " %s", IDENTIFIER_POINTER (node)); if (code == INTEGER_CST) { if (indent <= 4) print_node_brief (file, "type", TREE_TYPE (node), indent + 4); } else if (CODE_CONTAINS_STRUCT (code, TS_TYPED)) { print_node (file, "type", TREE_TYPE (node), indent + 4); if (TREE_TYPE (node)) indent_to (file, indent + 3); } if (!TYPE_P (node) && TREE_SIDE_EFFECTS (node)) fputs (" side-effects", file); if (TYPE_P (node) ? TYPE_READONLY (node) : TREE_READONLY (node)) fputs (" readonly", file); if (TYPE_P (node) && TYPE_ATOMIC (node)) fputs (" atomic", file); if (!TYPE_P (node) && TREE_CONSTANT (node)) fputs (" constant", file); else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node)) fputs (" sizes-gimplified", file); if (TYPE_P (node) && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node))) fprintf (file, " address-space-%d", TYPE_ADDR_SPACE (node)); if (TREE_ADDRESSABLE (node)) fputs (" addressable", file); if (TREE_THIS_VOLATILE (node)) fputs (" volatile", file); if (TREE_ASM_WRITTEN (node)) fputs (" asm_written", file); if (TREE_USED (node)) fputs (" used", file); if (TREE_NOTHROW (node)) fputs (" nothrow", file); if (TREE_PUBLIC (node)) fputs (" public", file); if (TREE_PRIVATE (node)) fputs (" private", file); if (TREE_PROTECTED (node)) fputs (" protected", file); if (TREE_STATIC (node)) fputs (code == CALL_EXPR ? " must-tail-call" : " static", file); if (TREE_DEPRECATED (node)) fputs (" deprecated", file); if (TREE_VISITED (node)) fputs (" visited", file); if (code != TREE_VEC && code != INTEGER_CST && code != SSA_NAME) { if (TREE_LANG_FLAG_0 (node)) fputs (" tree_0", file); if (TREE_LANG_FLAG_1 (node)) fputs (" tree_1", file); if (TREE_LANG_FLAG_2 (node)) fputs (" tree_2", file); if (TREE_LANG_FLAG_3 (node)) fputs (" tree_3", file); if (TREE_LANG_FLAG_4 (node)) fputs (" tree_4", file); if (TREE_LANG_FLAG_5 (node)) fputs (" tree_5", file); if (TREE_LANG_FLAG_6 (node)) fputs (" tree_6", file); } /* DECL_ nodes have additional attributes. */ switch (TREE_CODE_CLASS (code)) { case tcc_declaration: if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) { if (DECL_UNSIGNED (node)) fputs (" unsigned", file); if (DECL_IGNORED_P (node)) fputs (" ignored", file); if (DECL_ABSTRACT_P (node)) fputs (" abstract", file); if (DECL_EXTERNAL (node)) fputs (" external", file); if (DECL_NONLOCAL (node)) fputs (" nonlocal", file); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) { if (DECL_WEAK (node)) fputs (" weak", file); if (DECL_IN_SYSTEM_HEADER (node)) fputs (" in_system_header", file); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL) && code != LABEL_DECL && code != FUNCTION_DECL && DECL_REGISTER (node)) fputs (" regdecl", file); if (code == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node)) fputs (" suppress-debug", file); if (code == FUNCTION_DECL && DECL_FUNCTION_SPECIFIC_TARGET (node)) fputs (" function-specific-target", file); if (code == FUNCTION_DECL && DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node)) fputs (" function-specific-opt", file); if (code == FUNCTION_DECL && DECL_DECLARED_INLINE_P (node)) fputs (" autoinline", file); if (code == FUNCTION_DECL && DECL_BUILT_IN (node)) fputs (" built-in", file); if (code == FUNCTION_DECL && DECL_STATIC_CHAIN (node)) fputs (" static-chain", file); if (TREE_CODE (node) == FUNCTION_DECL && decl_is_tm_clone (node)) fputs (" tm-clone", file); if (code == FIELD_DECL && DECL_PACKED (node)) fputs (" packed", file); if (code == FIELD_DECL && DECL_BIT_FIELD (node)) fputs (" bit-field", file); if (code == FIELD_DECL && DECL_NONADDRESSABLE_P (node)) fputs (" nonaddressable", file); if (code == LABEL_DECL && EH_LANDING_PAD_NR (node)) fprintf (file, " landing-pad:%d", EH_LANDING_PAD_NR (node)); if (code == VAR_DECL && DECL_IN_TEXT_SECTION (node)) fputs (" in-text-section", file); if (code == VAR_DECL && DECL_IN_CONSTANT_POOL (node)) fputs (" in-constant-pool", file); if (code == VAR_DECL && DECL_COMMON (node)) fputs (" common", file); if (code == VAR_DECL && DECL_THREAD_LOCAL_P (node)) { fputs (" ", file); fputs (tls_model_names[DECL_TLS_MODEL (node)], file); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) { if (DECL_VIRTUAL_P (node)) fputs (" virtual", file); if (DECL_PRESERVE_P (node)) fputs (" preserve", file); if (DECL_LANG_FLAG_0 (node)) fputs (" decl_0", file); if (DECL_LANG_FLAG_1 (node)) fputs (" decl_1", file); if (DECL_LANG_FLAG_2 (node)) fputs (" decl_2", file); if (DECL_LANG_FLAG_3 (node)) fputs (" decl_3", file); if (DECL_LANG_FLAG_4 (node)) fputs (" decl_4", file); if (DECL_LANG_FLAG_5 (node)) fputs (" decl_5", file); if (DECL_LANG_FLAG_6 (node)) fputs (" decl_6", file); if (DECL_LANG_FLAG_7 (node)) fputs (" decl_7", file); mode = DECL_MODE (node); fprintf (file, " %s", GET_MODE_NAME (mode)); } if ((code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) && DECL_BY_REFERENCE (node)) fputs (" passed-by-reference", file); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS) && DECL_DEFER_OUTPUT (node)) fputs (" defer-output", file); xloc = expand_location (DECL_SOURCE_LOCATION (node)); fprintf (file, " file %s line %d col %d", xloc.file, xloc.line, xloc.column); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) { print_node (file, "size", DECL_SIZE (node), indent + 4); print_node (file, "unit size", DECL_SIZE_UNIT (node), indent + 4); if (code != FUNCTION_DECL || DECL_BUILT_IN (node)) indent_to (file, indent + 3); if (DECL_USER_ALIGN (node)) fprintf (file, " user"); fprintf (file, " align %d", DECL_ALIGN (node)); if (code == FIELD_DECL) fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED, DECL_OFFSET_ALIGN (node)); if (code == FUNCTION_DECL && DECL_BUILT_IN (node)) { if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD) fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node)); else fprintf (file, " built-in %s:%s", built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)], built_in_names[(int) DECL_FUNCTION_CODE (node)]); } } if (code == FIELD_DECL) { print_node (file, "offset", DECL_FIELD_OFFSET (node), indent + 4); print_node (file, "bit offset", DECL_FIELD_BIT_OFFSET (node), indent + 4); if (DECL_BIT_FIELD_TYPE (node)) print_node (file, "bit_field_type", DECL_BIT_FIELD_TYPE (node), indent + 4); } print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) { print_node_brief (file, "attributes", DECL_ATTRIBUTES (node), indent + 4); if (code != PARM_DECL) print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) { print_node_brief (file, "abstract_origin", DECL_ABSTRACT_ORIGIN (node), indent + 4); } if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON)) { print_node (file, "result", DECL_RESULT_FLD (node), indent + 4); } lang_hooks.print_decl (file, node, indent); if (DECL_RTL_SET_P (node)) { indent_to (file, indent + 4); print_rtl (file, DECL_RTL (node)); } if (code == PARM_DECL) { print_node (file, "arg-type", DECL_ARG_TYPE (node), indent + 4); if (DECL_INCOMING_RTL (node) != 0) { indent_to (file, indent + 4); fprintf (file, "incoming-rtl "); print_rtl (file, DECL_INCOMING_RTL (node)); } } else if (code == FUNCTION_DECL && DECL_STRUCT_FUNCTION (node) != 0) { print_node (file, "arguments", DECL_ARGUMENTS (node), indent + 4); indent_to (file, indent + 4); dump_addr (file, "struct-function ", DECL_STRUCT_FUNCTION (node)); } if ((code == VAR_DECL || code == PARM_DECL) && DECL_HAS_VALUE_EXPR_P (node)) print_node (file, "value-expr", DECL_VALUE_EXPR (node), indent + 4); /* Print the decl chain only if decl is at second level. */ if (indent == 4) print_node (file, "chain", TREE_CHAIN (node), indent + 4); else print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4); break; case tcc_type: if (TYPE_UNSIGNED (node)) fputs (" unsigned", file); if (TYPE_NO_FORCE_BLK (node)) fputs (" no-force-blk", file); if (TYPE_STRING_FLAG (node)) fputs (" string-flag", file); if (TYPE_NEEDS_CONSTRUCTING (node)) fputs (" needs-constructing", file); if ((code == RECORD_TYPE || code == UNION_TYPE || code == QUAL_UNION_TYPE || code == ARRAY_TYPE) && TYPE_REVERSE_STORAGE_ORDER (node)) fputs (" reverse-storage-order", file); /* The transparent-union flag is used for different things in different nodes. */ if ((code == UNION_TYPE || code == RECORD_TYPE) && TYPE_TRANSPARENT_AGGR (node)) fputs (" transparent-aggr", file); else if (code == ARRAY_TYPE && TYPE_NONALIASED_COMPONENT (node)) fputs (" nonaliased-component", file); if (TYPE_PACKED (node)) fputs (" packed", file); if (TYPE_RESTRICT (node)) fputs (" restrict", file); if (TYPE_LANG_FLAG_0 (node)) fputs (" type_0", file); if (TYPE_LANG_FLAG_1 (node)) fputs (" type_1", file); if (TYPE_LANG_FLAG_2 (node)) fputs (" type_2", file); if (TYPE_LANG_FLAG_3 (node)) fputs (" type_3", file); if (TYPE_LANG_FLAG_4 (node)) fputs (" type_4", file); if (TYPE_LANG_FLAG_5 (node)) fputs (" type_5", file); if (TYPE_LANG_FLAG_6 (node)) fputs (" type_6", file); if (TYPE_LANG_FLAG_7 (node)) fputs (" type_7", file); mode = TYPE_MODE (node); fprintf (file, " %s", GET_MODE_NAME (mode)); print_node (file, "size", TYPE_SIZE (node), indent + 4); print_node (file, "unit size", TYPE_SIZE_UNIT (node), indent + 4); indent_to (file, indent + 3); if (TYPE_USER_ALIGN (node)) fprintf (file, " user"); fprintf (file, " align %d symtab %d alias set " HOST_WIDE_INT_PRINT_DEC, TYPE_ALIGN (node), TYPE_SYMTAB_ADDRESS (node), (HOST_WIDE_INT) TYPE_ALIAS_SET (node)); if (TYPE_STRUCTURAL_EQUALITY_P (node)) fprintf (file, " structural equality"); else dump_addr (file, " canonical type ", TYPE_CANONICAL (node)); print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4); if (INTEGRAL_TYPE_P (node) || code == REAL_TYPE || code == FIXED_POINT_TYPE) { fprintf (file, " precision %d", TYPE_PRECISION (node)); print_node_brief (file, "min", TYPE_MIN_VALUE (node), indent + 4); print_node_brief (file, "max", TYPE_MAX_VALUE (node), indent + 4); } if (code == ENUMERAL_TYPE) print_node (file, "values", TYPE_VALUES (node), indent + 4); else if (code == ARRAY_TYPE) print_node (file, "domain", TYPE_DOMAIN (node), indent + 4); else if (code == VECTOR_TYPE) fprintf (file, " nunits %d", (int) TYPE_VECTOR_SUBPARTS (node)); else if (code == RECORD_TYPE || code == UNION_TYPE || code == QUAL_UNION_TYPE) print_node (file, "fields", TYPE_FIELDS (node), indent + 4); else if (code == FUNCTION_TYPE || code == METHOD_TYPE) { if (TYPE_METHOD_BASETYPE (node)) print_node_brief (file, "method basetype", TYPE_METHOD_BASETYPE (node), indent + 4); print_node (file, "arg-types", TYPE_ARG_TYPES (node), indent + 4); } else if (code == OFFSET_TYPE) print_node_brief (file, "basetype", TYPE_OFFSET_BASETYPE (node), indent + 4); if (TYPE_CONTEXT (node)) print_node_brief (file, "context", TYPE_CONTEXT (node), indent + 4); lang_hooks.print_type (file, node, indent); if (TYPE_POINTER_TO (node) || TREE_CHAIN (node)) indent_to (file, indent + 3); print_node_brief (file, "pointer_to_this", TYPE_POINTER_TO (node), indent + 4); print_node_brief (file, "reference_to_this", TYPE_REFERENCE_TO (node), indent + 4); print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4); break; case tcc_expression: case tcc_comparison: case tcc_unary: case tcc_binary: case tcc_reference: case tcc_statement: case tcc_vl_exp: if (code == BIND_EXPR) { print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4); print_node (file, "body", TREE_OPERAND (node, 1), indent + 4); print_node (file, "block", TREE_OPERAND (node, 2), indent + 4); break; } if (code == CALL_EXPR) { call_expr_arg_iterator iter; tree arg; print_node (file, "fn", CALL_EXPR_FN (node), indent + 4); print_node (file, "static_chain", CALL_EXPR_STATIC_CHAIN (node), indent + 4); i = 0; FOR_EACH_CALL_EXPR_ARG (arg, iter, node) { char temp[10]; sprintf (temp, "arg %d", i); print_node (file, temp, arg, indent + 4); i++; } }
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); }