static void unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { DECL_MODE (expr) = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); DECL_NONLOCAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_VIRTUAL_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IGNORED_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_ABSTRACT (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_ARTIFICIAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_PRESERVE_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_DEBUG_EXPR_IS_FROM (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_EXTERNAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_ALIGN (expr) = (unsigned) bp_unpack_var_len_unsigned (bp); if (TREE_CODE (expr) == LABEL_DECL) { DECL_ERROR_ISSUED (expr) = (unsigned) bp_unpack_value (bp, 1); EH_LANDING_PAD_NR (expr) = (int) bp_unpack_var_len_unsigned (bp); /* Always assume an initial value of -1 for LABEL_DECL_UID to force gimple_set_bb to recreate label_to_block_map. */ LABEL_DECL_UID (expr) = -1; } if (TREE_CODE (expr) == FIELD_DECL) { DECL_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_NONADDRESSABLE_P (expr) = (unsigned) bp_unpack_value (bp, 1); expr->decl_common.off_align = bp_unpack_value (bp, 8); } if (TREE_CODE (expr) == RESULT_DECL || TREE_CODE (expr) == PARM_DECL || TREE_CODE (expr) == VAR_DECL) { DECL_BY_REFERENCE (expr) = (unsigned) bp_unpack_value (bp, 1); if (TREE_CODE (expr) == VAR_DECL || TREE_CODE (expr) == PARM_DECL) DECL_HAS_VALUE_EXPR_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_RESTRICTED_P (expr) = (unsigned) bp_unpack_value (bp, 1); } }
static void pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr)); bp_pack_value (bp, DECL_NONLOCAL (expr), 1); bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1); bp_pack_value (bp, DECL_IGNORED_P (expr), 1); bp_pack_value (bp, DECL_ABSTRACT (expr), 1); bp_pack_value (bp, DECL_ARTIFICIAL (expr), 1); bp_pack_value (bp, DECL_USER_ALIGN (expr), 1); bp_pack_value (bp, DECL_PRESERVE_P (expr), 1); bp_pack_value (bp, DECL_DEBUG_EXPR_IS_FROM (expr), 1); bp_pack_value (bp, DECL_EXTERNAL (expr), 1); bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1); bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr)); if (TREE_CODE (expr) == LABEL_DECL) { /* Note that we do not write LABEL_DECL_UID. The reader will always assume an initial value of -1 so that the label_to_block_map is recreated by gimple_set_bb. */ bp_pack_value (bp, DECL_ERROR_ISSUED (expr), 1); bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr)); } if (TREE_CODE (expr) == FIELD_DECL) { bp_pack_value (bp, DECL_PACKED (expr), 1); bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1); bp_pack_value (bp, expr->decl_common.off_align, 8); } if (TREE_CODE (expr) == RESULT_DECL || TREE_CODE (expr) == PARM_DECL || TREE_CODE (expr) == VAR_DECL) { bp_pack_value (bp, DECL_BY_REFERENCE (expr), 1); if (TREE_CODE (expr) == VAR_DECL || TREE_CODE (expr) == PARM_DECL) bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1); bp_pack_value (bp, DECL_RESTRICTED_P (expr), 1); } }
static bool can_remove_node_now_p_1 (struct cgraph_node *node) { /* FIXME: When address is taken of DECL_EXTERNAL function we still can remove its offline copy, but we would need to keep unanalyzed node in the callgraph so references can point to it. */ return (!node->address_taken && !ipa_ref_has_aliases_p (&node->ref_list) && !node->used_as_abstract_origin && cgraph_can_remove_if_no_direct_calls_p (node) /* Inlining might enable more devirtualizing, so we want to remove those only after all devirtualizable virtual calls are processed. Lacking may edges in callgraph we just preserve them post inlining. */ && !DECL_VIRTUAL_P (node->decl) /* During early inlining some unanalyzed cgraph nodes might be in the callgraph and they might reffer the function in question. */ && !cgraph_new_nodes); }
symtab_node symtab_nonoverwritable_alias (symtab_node node) { tree new_decl; symtab_node new_node = NULL; symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1, (void *)&new_node, true); if (new_node) return new_node; new_decl = copy_node (node->symbol.decl); DECL_NAME (new_decl) = clone_function_name (node->symbol.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->symbol.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 = (symtab_node) cgraph_create_function_alias (new_decl, node->symbol.decl); } else new_node = (symtab_node) varpool_create_variable_alias (new_decl, node->symbol.decl); symtab_resolve_alias (new_node, node); return new_node; }
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++; } }
bool i386_pe_type_dllimport_p (tree decl) { gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL); if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL) return false; /* We ignore the dllimport attribute for inline member functions. This differs from MSVC behavior which treats it like GNUC 'extern inline' extension. Also ignore for template instantiations with linkonce semantics and artificial methods. */ if (TREE_CODE (decl) == FUNCTION_DECL && (DECL_DECLARED_INLINE_P (decl) || DECL_TEMPLATE_INSTANTIATION (decl) || DECL_ARTIFICIAL (decl))) return false; /* Since we can't treat a pointer to a dllimport'd symbol as a constant address, we turn off the attribute on C++ virtual methods to allow creation of vtables using thunks. */ else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE && DECL_VIRTUAL_P (decl)) { /* Even though we ignore the attribute from the start, warn if we later see an out-of class definition, as we do for other member functions in tree.c:merge_dllimport_decl_attributes. If this is the key method, the definition may affect the import-export status of vtables, depending on how we handle MULTIPLE_SYMBOL_SPACES in cp/decl2.c. */ if (DECL_INITIAL (decl)) { warning (OPT_Wattributes, "%q+D redeclared without dllimport attribute: " "previous dllimport ignored", decl); #ifdef PE_DLL_DEBUG if (decl == CLASSTYPE_KEY_METHOD (DECL_CONTEXT (decl))) warning (OPT_Wattributes, "key method %q+D of dllimport'd class defined" decl); #endif } return false; } /* Don't mark defined functions as dllimport. This code will only be reached if we see a non-inline function defined out-of-class. */ else if (TREE_CODE (decl) == FUNCTION_DECL && (DECL_INITIAL (decl))) return false; /* Don't allow definitions of static data members in dllimport class, If vtable data is marked as DECL_EXTERNAL, import it; otherwise just ignore the class attribute. */ else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) { if (!DECL_VIRTUAL_P (decl)) error ("definition of static data member %q+D of " "dllimport'd class", decl); return false; } return true; }
static int i386_pe_dllimport_p (tree decl) { tree imp; int context_imp = 0; if (TREE_CODE (decl) == FUNCTION_DECL && TARGET_NOP_FUN_DLLIMPORT) return 0; if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) return 0; imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)); /* Class members get the dllimport status of their class. */ if (!imp && associated_type (decl)) { imp = lookup_attribute ("dllimport", TYPE_ATTRIBUTES (associated_type (decl))); if (imp) context_imp = 1; } if (imp) { /* Don't mark defined functions as dllimport. If the definition itself was marked with dllimport, than ix86_handle_dll_attribute reports an error. This handles the case when the definition overrides an earlier declaration. */ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) && !DECL_INLINE (decl)) { /* Don't warn about artificial methods. */ if (!DECL_ARTIFICIAL (decl)) warning ("%Jfunction '%D' is defined after prior declaration " "as dllimport: attribute ignored", decl, decl); return 0; } /* We ignore the dllimport attribute for inline member functions. This differs from MSVC behavior which treats it like GNUC 'extern inline' extension. */ else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)) { if (extra_warnings) warning ("%Jinline function '%D' is declared as dllimport: " "attribute ignored.", decl, decl); return 0; } /* Don't allow definitions of static data members in dllimport class, Just ignore attribute for vtable data. */ else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl) && context_imp) { if (!DECL_VIRTUAL_P (decl)) error ("%Jdefinition of static data member '%D' of " "dllimport'd class.", decl, decl); return 0; } /* Since we can't treat a pointer to a dllimport'd symbol as a constant address, we turn off the attribute on C++ virtual methods to allow creation of vtables using thunks. Don't mark artificial methods either (in associated_type, only COMDAT artificial method get import status from class context). */ else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl))) return 0; return 1; } return 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); }
void dump_symtab_base (FILE *f, symtab_node node) { static const char * const visibility_types[] = { "default", "protected", "hidden", "internal" }; fprintf (f, "%s/%i (%s)", symtab_node_asm_name (node), node->symbol.order, symtab_node_name (node)); dump_addr (f, " @", (void *)node); fprintf (f, "\n Type: %s\n", symtab_type_names[node->symbol.type]); fprintf (f, " Visibility:"); if (node->symbol.in_other_partition) fprintf (f, " in_other_partition"); if (node->symbol.used_from_other_partition) fprintf (f, " used_from_other_partition"); if (node->symbol.force_output) fprintf (f, " force_output"); if (node->symbol.resolution != LDPR_UNKNOWN) fprintf (f, " %s", ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]); if (TREE_ASM_WRITTEN (node->symbol.decl)) fprintf (f, " asm_written"); if (DECL_EXTERNAL (node->symbol.decl)) fprintf (f, " external"); if (TREE_PUBLIC (node->symbol.decl)) fprintf (f, " public"); if (DECL_COMMON (node->symbol.decl)) fprintf (f, " common"); if (DECL_WEAK (node->symbol.decl)) fprintf (f, " weak"); if (DECL_DLLIMPORT_P (node->symbol.decl)) fprintf (f, " dll_import"); if (DECL_COMDAT (node->symbol.decl)) fprintf (f, " comdat"); if (DECL_COMDAT_GROUP (node->symbol.decl)) fprintf (f, " comdat_group:%s", IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->symbol.decl))); if (DECL_ONE_ONLY (node->symbol.decl)) fprintf (f, " one_only"); if (DECL_SECTION_NAME (node->symbol.decl)) fprintf (f, " section_name:%s", TREE_STRING_POINTER (DECL_SECTION_NAME (node->symbol.decl))); if (DECL_VISIBILITY_SPECIFIED (node->symbol.decl)) fprintf (f, " visibility_specified"); if (DECL_VISIBILITY (node->symbol.decl)) fprintf (f, " visibility:%s", visibility_types [DECL_VISIBILITY (node->symbol.decl)]); if (DECL_VIRTUAL_P (node->symbol.decl)) fprintf (f, " virtual"); if (DECL_ARTIFICIAL (node->symbol.decl)) fprintf (f, " artificial"); if (TREE_CODE (node->symbol.decl) == FUNCTION_DECL) { if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl)) fprintf (f, " constructor"); if (DECL_STATIC_DESTRUCTOR (node->symbol.decl)) fprintf (f, " destructor"); } fprintf (f, "\n"); if (node->symbol.same_comdat_group) fprintf (f, " Same comdat group as: %s/%i\n", symtab_node_asm_name (node->symbol.same_comdat_group), node->symbol.same_comdat_group->symbol.order); if (node->symbol.next_sharing_asm_name) fprintf (f, " next sharing asm name: %i\n", node->symbol.next_sharing_asm_name->symbol.order); if (node->symbol.previous_sharing_asm_name) fprintf (f, " previous sharing asm name: %i\n", node->symbol.previous_sharing_asm_name->symbol.order); if (node->symbol.address_taken) fprintf (f, " Address is taken.\n"); if (node->symbol.aux) { fprintf (f, " Aux:"); dump_addr (f, " @", (void *)node->symbol.aux); } fprintf (f, " References: "); ipa_dump_references (f, &node->symbol.ref_list); fprintf (f, " Referring: "); ipa_dump_referring (f, &node->symbol.ref_list); }
bool cp_dump_tree (void* dump_info, tree t) { enum tree_code code; dump_info_p di = (dump_info_p) dump_info; /* Figure out what kind of node this is. */ code = TREE_CODE (t); if (DECL_P (t)) { if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus) dump_string (di, language_to_string (DECL_LANGUAGE (t))); } switch (code) { case IDENTIFIER_NODE: if (IDENTIFIER_OPNAME_P (t)) { dump_string (di, "operator"); return true; } else if (IDENTIFIER_TYPENAME_P (t)) { dump_child ("tynm", TREE_TYPE (t)); return true; } break; case OFFSET_TYPE: dump_string (di, "ptrmem"); dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t)); dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t)); return true; case RECORD_TYPE: if (TYPE_PTRMEMFUNC_P (t)) { dump_string (di, "ptrmem"); dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t)); dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t)); return true; } /* Fall through. */ case UNION_TYPE: /* Is it a type used as a base? */ if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t) && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t) { dump_child ("bfld", TYPE_CONTEXT (t)); return true; } if (! IS_AGGR_TYPE (t)) break; dump_child ("vfld", TYPE_VFIELD (t)); if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t)) dump_string(di, "spec"); if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t)) { int i; tree binfo; tree base_binfo; for (binfo = TYPE_BINFO (t), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) { dump_child ("base", BINFO_TYPE (base_binfo)); if (BINFO_VIRTUAL_P (base_binfo)) dump_string (di, "virtual"); dump_access (di, base_binfo); } } break; case FIELD_DECL: dump_access (di, t); if (DECL_MUTABLE_P (t)) dump_string(di, "mutable"); break; case VAR_DECL: if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE) dump_access (di, t); if (TREE_STATIC (t) && !TREE_PUBLIC (t)) dump_string (di, "static"); break; case FUNCTION_DECL: if (!DECL_THUNK_P (t)) { if (DECL_OVERLOADED_OPERATOR_P (t)) { dump_string (di, "operator"); dump_op (di, t); } if (DECL_FUNCTION_MEMBER_P (t)) { dump_string (di, "member"); dump_access (di, t); } if (DECL_PURE_VIRTUAL_P (t)) dump_string (di, "pure"); if (DECL_VIRTUAL_P (t)) dump_string (di, "virtual"); if (DECL_CONSTRUCTOR_P (t)) dump_string (di, "constructor"); if (DECL_DESTRUCTOR_P (t)) dump_string (di, "destructor"); if (DECL_CONV_FN_P (t)) dump_string (di, "conversion"); if (DECL_GLOBAL_CTOR_P (t)) dump_string (di, "global init"); if (DECL_GLOBAL_DTOR_P (t)) dump_string (di, "global fini"); if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)) dump_string (di, "pseudo tmpl"); } else { tree virt = THUNK_VIRTUAL_OFFSET (t); dump_string (di, "thunk"); if (DECL_THIS_THUNK_P (t)) dump_string (di, "this adjusting"); else { dump_string (di, "result adjusting"); if (virt) virt = BINFO_VPTR_FIELD (virt); } dump_int (di, "fixd", THUNK_FIXED_OFFSET (t)); if (virt) dump_int (di, "virt", tree_low_cst (virt, 0)); dump_child ("fn", DECL_INITIAL (t)); } break; case NAMESPACE_DECL: if (DECL_NAMESPACE_ALIAS (t)) dump_child ("alis", DECL_NAMESPACE_ALIAS (t)); else if (!dump_flag (di, TDF_SLIM, t)) dump_child ("dcls", cp_namespace_decls (t)); break; case TEMPLATE_DECL: dump_child ("rslt", DECL_TEMPLATE_RESULT (t)); dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t)); dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t)); dump_child ("prms", DECL_TEMPLATE_PARMS (t)); break; case OVERLOAD: dump_child ("crnt", OVL_CURRENT (t)); dump_child ("chan", OVL_CHAIN (t)); break; case TRY_BLOCK: dump_stmt (di, t); if (CLEANUP_P (t)) dump_string (di, "cleanup"); dump_child ("body", TRY_STMTS (t)); dump_child ("hdlr", TRY_HANDLERS (t)); break; case EH_SPEC_BLOCK: dump_stmt (di, t); dump_child ("body", EH_SPEC_STMTS (t)); dump_child ("raises", EH_SPEC_RAISES (t)); break; case PTRMEM_CST: dump_child ("clas", PTRMEM_CST_CLASS (t)); dump_child ("mbr", PTRMEM_CST_MEMBER (t)); break; case THROW_EXPR: /* These nodes are unary, but do not have code class `1'. */ dump_child ("op 0", TREE_OPERAND (t, 0)); break; case AGGR_INIT_EXPR: dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t)); dump_child ("fn", TREE_OPERAND (t, 0)); dump_child ("args", TREE_OPERAND (t, 1)); dump_child ("decl", TREE_OPERAND (t, 2)); break; case HANDLER: dump_stmt (di, t); dump_child ("parm", HANDLER_PARMS (t)); dump_child ("body", HANDLER_BODY (t)); break; case MUST_NOT_THROW_EXPR: dump_stmt (di, t); dump_child ("body", TREE_OPERAND (t, 0)); break; case USING_STMT: dump_stmt (di, t); dump_child ("nmsp", USING_STMT_NAMESPACE (t)); break; case CLEANUP_STMT: dump_stmt (di, t); dump_child ("decl", CLEANUP_DECL (t)); dump_child ("expr", CLEANUP_EXPR (t)); dump_child ("body", CLEANUP_BODY (t)); break; case IF_STMT: dump_stmt (di, t); dump_child ("cond", IF_COND (t)); dump_child ("then", THEN_CLAUSE (t)); dump_child ("else", ELSE_CLAUSE (t)); break; default: break; } return c_dump_tree (di, t); }
static void lto_varpool_replace_node (varpool_node *vnode, varpool_node *prevailing_node) { gcc_assert (!vnode->definition || prevailing_node->definition); gcc_assert (!vnode->analyzed || prevailing_node->analyzed); prevailing_node->clone_referring (vnode); if (vnode->force_output) prevailing_node->force_output = true; if (vnode->forced_by_abi) prevailing_node->forced_by_abi = true; /* Be sure we can garbage collect the initializer. */ if (DECL_INITIAL (vnode->decl) && vnode->decl != prevailing_node->decl) DECL_INITIAL (vnode->decl) = error_mark_node; /* Check and report ODR violations on virtual tables. */ if (DECL_VIRTUAL_P (vnode->decl) || DECL_VIRTUAL_P (prevailing_node->decl)) compare_virtual_tables (prevailing_node, vnode); if (vnode->tls_model != prevailing_node->tls_model) { bool error = false; /* Non-TLS and TLS never mix together. Also emulated model is not compatible with anything else. */ if (prevailing_node->tls_model == TLS_MODEL_NONE || prevailing_node->tls_model == TLS_MODEL_EMULATED || vnode->tls_model == TLS_MODEL_NONE || vnode->tls_model == TLS_MODEL_EMULATED) error = true; /* Linked is silently supporting transitions GD -> IE, GD -> LE, LD -> LE, IE -> LE, LD -> IE. Do the same transitions and error out on others. */ else if ((prevailing_node->tls_model == TLS_MODEL_REAL || prevailing_node->tls_model == TLS_MODEL_LOCAL_DYNAMIC) && (vnode->tls_model == TLS_MODEL_INITIAL_EXEC || vnode->tls_model == TLS_MODEL_LOCAL_EXEC)) prevailing_node->tls_model = vnode->tls_model; else if ((vnode->tls_model == TLS_MODEL_REAL || vnode->tls_model == TLS_MODEL_LOCAL_DYNAMIC) && (prevailing_node->tls_model == TLS_MODEL_INITIAL_EXEC || prevailing_node->tls_model == TLS_MODEL_LOCAL_EXEC)) ; else if (prevailing_node->tls_model == TLS_MODEL_INITIAL_EXEC && vnode->tls_model == TLS_MODEL_LOCAL_EXEC) prevailing_node->tls_model = vnode->tls_model; else if (vnode->tls_model == TLS_MODEL_INITIAL_EXEC && prevailing_node->tls_model == TLS_MODEL_LOCAL_EXEC) ; else error = true; if (error) { error_at (DECL_SOURCE_LOCATION (vnode->decl), "%qD is defined with tls model %s", vnode->decl, tls_model_names [vnode->tls_model]); inform (DECL_SOURCE_LOCATION (prevailing_node->decl), "previously defined here as %s", tls_model_names [prevailing_node->tls_model]); } } /* Finally remove the replaced node. */ vnode->remove (); }
void symtab_node::dump_base (FILE *f) { static const char * const visibility_types[] = { "default", "protected", "hidden", "internal" }; fprintf (f, "%s/%i (%s)", asm_name (), order, name ()); dump_addr (f, " @", (void *)this); fprintf (f, "\n Type: %s", symtab_type_names[type]); if (definition) fprintf (f, " definition"); if (analyzed) fprintf (f, " analyzed"); if (alias) fprintf (f, " alias"); if (weakref) fprintf (f, " weakref"); if (cpp_implicit_alias) fprintf (f, " cpp_implicit_alias"); if (alias_target) fprintf (f, " target:%s", DECL_P (alias_target) ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (alias_target)) : IDENTIFIER_POINTER (alias_target)); if (body_removed) fprintf (f, "\n Body removed by symtab_remove_unreachable_nodes"); fprintf (f, "\n Visibility:"); if (in_other_partition) fprintf (f, " in_other_partition"); if (used_from_other_partition) fprintf (f, " used_from_other_partition"); if (force_output) fprintf (f, " force_output"); if (forced_by_abi) fprintf (f, " forced_by_abi"); if (externally_visible) fprintf (f, " externally_visible"); if (resolution != LDPR_UNKNOWN) fprintf (f, " %s", ld_plugin_symbol_resolution_names[(int)resolution]); if (TREE_ASM_WRITTEN (decl)) fprintf (f, " asm_written"); if (DECL_EXTERNAL (decl)) fprintf (f, " external"); if (TREE_PUBLIC (decl)) fprintf (f, " public"); if (DECL_COMMON (decl)) fprintf (f, " common"); if (DECL_WEAK (decl)) fprintf (f, " weak"); if (DECL_DLLIMPORT_P (decl)) fprintf (f, " dll_import"); if (DECL_COMDAT (decl)) fprintf (f, " comdat"); if (get_comdat_group ()) fprintf (f, " comdat_group:%s", IDENTIFIER_POINTER (get_comdat_group_id ())); if (DECL_ONE_ONLY (decl)) fprintf (f, " one_only"); if (get_section ()) fprintf (f, " section:%s", get_section ()); if (implicit_section) fprintf (f," (implicit_section)"); if (DECL_VISIBILITY_SPECIFIED (decl)) fprintf (f, " visibility_specified"); if (DECL_VISIBILITY (decl)) fprintf (f, " visibility:%s", visibility_types [DECL_VISIBILITY (decl)]); if (DECL_VIRTUAL_P (decl)) fprintf (f, " virtual"); if (DECL_ARTIFICIAL (decl)) fprintf (f, " artificial"); if (TREE_CODE (decl) == FUNCTION_DECL) { if (DECL_STATIC_CONSTRUCTOR (decl)) fprintf (f, " constructor"); if (DECL_STATIC_DESTRUCTOR (decl)) fprintf (f, " destructor"); } fprintf (f, "\n"); if (same_comdat_group) fprintf (f, " Same comdat group as: %s/%i\n", same_comdat_group->asm_name (), same_comdat_group->order); if (next_sharing_asm_name) fprintf (f, " next sharing asm name: %i\n", next_sharing_asm_name->order); if (previous_sharing_asm_name) fprintf (f, " previous sharing asm name: %i\n", previous_sharing_asm_name->order); if (address_taken) fprintf (f, " Address is taken.\n"); if (aux) { fprintf (f, " Aux:"); dump_addr (f, " @", (void *)aux); } fprintf (f, " References: "); dump_references (f); fprintf (f, " Referring: "); dump_referring (f); if (lto_file_data) fprintf (f, " Read from file: %s\n", lto_file_data->file_name); }
void field_DECL_VIRTUAL_P(tree t) { if (DECL_VIRTUAL_P(t)) { fprintf( code_outputfile,"DECL_VIRTUAL_P(%d),\n",DECL_VIRTUAL_P(t)); } } // vtable