X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdwarf2out.c;h=86512a4f8f5f8d4e74a62e9263492c2a484b458e;hb=ac8a72dec9e57bd3380048ab0cef058c396cf550;hp=55947932ddb0fa2f916d3b9ad3a40c4096471990;hpb=1b6ad37661ec49431e314afafa880338e1cfc872;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 55947932ddb..86512a4f8f5 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -149,7 +149,7 @@ collect2_eh_frame_section (void) data_section (); ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); - (*targetm.asm_out.globalize_label) (asm_out_file, IDENTIFIER_POINTER (label)); + targetm.asm_out.globalize_label (asm_out_file, IDENTIFIER_POINTER (label)); ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); } @@ -243,6 +243,7 @@ typedef struct cfa_loc GTY(()) typedef struct dw_fde_struct GTY(()) { + tree decl; const char *dw_fde_begin; const char *dw_fde_current_label; const char *dw_fde_end; @@ -391,7 +392,9 @@ static void def_cfa_1 (const char *, dw_cfa_location *); #define FUNC_END_LABEL "LFE" #endif +#ifndef FRAME_BEGIN_LABEL #define FRAME_BEGIN_LABEL "Lframe" +#endif #define CIE_AFTER_SIZE_LABEL "LSCIE" #define CIE_END_LABEL "LECIE" #define FDE_LABEL "LSFDE" @@ -1942,6 +1945,22 @@ output_call_frame_info (int for_eh) if (fde_table_in_use == 0) return; + /* If we make FDEs linkonce, we may have to emit an empty label for + an FDE that wouldn't otherwise be emitted. We want to avoid + having an FDE kept around when the function it refers to is + discarded. (Example where this matters: a primary function + template in C++ requires EH information, but an explicit + specialization doesn't. */ + if (TARGET_USES_WEAK_UNWIND_INFO + && ! flag_asynchronous_unwind_tables + && for_eh) + for (i = 0; i < fde_table_in_use; i++) + if ((fde_table[i].nothrow || fde_table[i].all_throwers_are_sibcalls) + && !fde_table[i].uses_eh_lsda + && ! DECL_ONE_ONLY (fde_table[i].decl)) + targetm.asm_out.unwind_label (asm_out_file, fde_table[i].decl, + /* empty */ 1); + /* If we don't have any functions we'll want to unwind out of, don't emit any EH unwind information. Note that if exceptions aren't enabled, we won't have collected nothrow information, and if we @@ -1953,6 +1972,9 @@ output_call_frame_info (int for_eh) for (i = 0; i < fde_table_in_use; i++) if (fde_table[i].uses_eh_lsda) any_eh_needed = any_lsda_needed = true; + else if (TARGET_USES_WEAK_UNWIND_INFO + && DECL_ONE_ONLY (fde_table[i].decl)) + any_eh_needed = 1; else if (! fde_table[i].nothrow && ! fde_table[i].all_throwers_are_sibcalls) any_eh_needed = true; @@ -1966,7 +1988,7 @@ output_call_frame_info (int for_eh) app_enable (); if (for_eh) - (*targetm.asm_out.eh_frame_section) (); + targetm.asm_out.eh_frame_section (); else named_section_flags (DEBUG_FRAME_SECTION, SECTION_DEBUG); @@ -2004,7 +2026,9 @@ output_call_frame_info (int for_eh) P Indicates the presence of an encoding + language personality routine in the CIE augmentation. */ - fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); + fde_encoding = TARGET_USES_WEAK_UNWIND_INFO + ? ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1) + : ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1); lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); @@ -2095,10 +2119,12 @@ output_call_frame_info (int for_eh) /* Don't emit EH unwind info for leaf functions that don't need it. */ if (for_eh && !flag_asynchronous_unwind_tables && flag_exceptions && (fde->nothrow || fde->all_throwers_are_sibcalls) + && (! TARGET_USES_WEAK_UNWIND_INFO || ! DECL_ONE_ONLY (fde->decl)) && !fde->uses_eh_lsda) continue; - (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2); + targetm.asm_out.unwind_label (asm_out_file, fde->decl, /* empty */ 0); + targetm.asm_out.internal_label (asm_out_file, FDE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2); dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, @@ -2113,9 +2139,16 @@ output_call_frame_info (int for_eh) if (for_eh) { - dw2_asm_output_encoded_addr_rtx (fde_encoding, - gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin), - "FDE initial location"); + if (TARGET_USES_WEAK_UNWIND_INFO + && DECL_ONE_ONLY (fde->decl)) + dw2_asm_output_encoded_addr_rtx (fde_encoding, + gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (fde->decl))), + "FDE initial location"); + else + dw2_asm_output_encoded_addr_rtx (fde_encoding, + gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin), + "FDE initial location"); dw2_asm_output_delta (size_of_encoded_value (fde_encoding), fde->dw_fde_end, fde->dw_fde_begin, "FDE address range"); @@ -2248,6 +2281,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, /* Add the new FDE at the end of the fde_table. */ fde = &fde_table[fde_table_in_use++]; + fde->decl = current_function_decl; fde->dw_fde_begin = xstrdup (label); fde->dw_fde_current_label = NULL; fde->dw_fde_end = NULL; @@ -2385,7 +2419,7 @@ typedef struct dw_val_struct GTY(()) unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset; dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list; dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc; - HOST_WIDE_INT GTY ((default (""))) val_int; + HOST_WIDE_INT GTY ((default)) val_int; unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned; dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long; dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec; @@ -6598,7 +6632,7 @@ output_die_symbol (dw_die_ref die) /* We make these global, not weak; if the target doesn't support .linkonce, it doesn't support combining the sections, so debugging will break. */ - (*targetm.asm_out.globalize_label) (asm_out_file, sym); + targetm.asm_out.globalize_label (asm_out_file, sym); ASM_OUTPUT_LABEL (asm_out_file, sym); } @@ -6949,7 +6983,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty) static const char * dwarf2_name (tree decl, int scope) { - return (*lang_hooks.decl_printable_name) (decl, scope ? 1 : 0); + return lang_hooks.decl_printable_name (decl, scope ? 1 : 0); } /* Add a new entry to .debug_pubnames if appropriate. */ @@ -7819,7 +7853,7 @@ base_type_die (tree type) || ! strcmp (type_name, "signed char") || ! strcmp (type_name, "unsigned char")))) { - if (TREE_UNSIGNED (type)) + if (TYPE_UNSIGNED (type)) encoding = DW_ATE_unsigned; else encoding = DW_ATE_signed; @@ -7829,7 +7863,7 @@ base_type_die (tree type) case CHAR_TYPE: /* GNU Pascal/Ada CHAR type. Not used in C. */ - if (TREE_UNSIGNED (type)) + if (TYPE_UNSIGNED (type)) encoding = DW_ATE_unsigned_char; else encoding = DW_ATE_signed_char; @@ -7966,15 +8000,51 @@ is_subrange_type (tree type) { tree subtype = TREE_TYPE (type); - if (TREE_CODE (type) == INTEGER_TYPE - && subtype != NULL_TREE) + /* Subrange types are identified by the fact that they are integer + types, and that they have a subtype which is either an integer type + or an enumeral type. */ + + if (TREE_CODE (type) != INTEGER_TYPE + || subtype == NULL_TREE) + return false; + + if (TREE_CODE (subtype) != INTEGER_TYPE + && TREE_CODE (subtype) != ENUMERAL_TYPE) + return false; + + if (TREE_CODE (type) == TREE_CODE (subtype) + && int_size_in_bytes (type) == int_size_in_bytes (subtype) + && TYPE_MIN_VALUE (type) != NULL + && TYPE_MIN_VALUE (subtype) != NULL + && tree_int_cst_equal (TYPE_MIN_VALUE (type), TYPE_MIN_VALUE (subtype)) + && TYPE_MAX_VALUE (type) != NULL + && TYPE_MAX_VALUE (subtype) != NULL + && tree_int_cst_equal (TYPE_MAX_VALUE (type), TYPE_MAX_VALUE (subtype))) { - if (TREE_CODE (subtype) == INTEGER_TYPE) - return true; - if (TREE_CODE (subtype) == ENUMERAL_TYPE) - return true; + /* The type and its subtype have the same representation. If in + addition the two types also have the same name, then the given + type is not a subrange type, but rather a plain base type. */ + /* FIXME: brobecker/2004-03-22: + Sizetype INTEGER_CSTs nodes are canonicalized. It should + therefore be sufficient to check the TYPE_SIZE node pointers + rather than checking the actual size. Unfortunately, we have + found some cases, such as in the Ada "integer" type, where + this is not the case. Until this problem is solved, we need to + keep checking the actual size. */ + tree type_name = TYPE_NAME (type); + tree subtype_name = TYPE_NAME (subtype); + + if (type_name != NULL && TREE_CODE (type_name) == TYPE_DECL) + type_name = DECL_NAME (type_name); + + if (subtype_name != NULL && TREE_CODE (subtype_name) == TYPE_DECL) + subtype_name = DECL_NAME (subtype_name); + + if (type_name == subtype_name) + return false; } - return false; + + return true; } /* Given a pointer to a tree node for a subrange type, return a pointer @@ -7987,14 +8057,15 @@ subrange_type_die (tree type, dw_die_ref context_die) dw_die_ref subrange_die; tree name = TYPE_NAME (type); const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type); + tree subtype = TREE_TYPE (type); if (context_die == NULL) context_die = comp_unit_die; - if (TREE_CODE (TREE_TYPE (type)) == ENUMERAL_TYPE) - subtype_die = gen_enumeration_type_die (TREE_TYPE (type), context_die); + if (TREE_CODE (subtype) == ENUMERAL_TYPE) + subtype_die = gen_enumeration_type_die (subtype, context_die); else - subtype_die = base_type_die (TREE_TYPE (type)); + subtype_die = base_type_die (subtype); subrange_die = new_die (DW_TAG_subrange_type, context_die, type); @@ -8005,7 +8076,7 @@ subrange_type_die (tree type, dw_die_ref context_die) add_name_attribute (subrange_die, IDENTIFIER_POINTER (name)); } - if (int_size_in_bytes (TREE_TYPE (type)) != size_in_bytes) + if (int_size_in_bytes (subtype) != size_in_bytes) { /* The size of the subrange type and its base type do not match, so we need to generate a size attribute for the subrange type. */ @@ -8195,7 +8266,7 @@ reg_loc_descriptor (rtx rtl) return 0; reg = reg_number (rtl); - regs = (*targetm.dwarf_register_span) (rtl); + regs = targetm.dwarf_register_span (rtl); if (hard_regno_nregs[reg][GET_MODE (rtl)] > 1 || regs) @@ -8370,7 +8441,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg) actually within the array. That's *not* necessarily the same as the zeroth element of the array. */ - rtl = (*targetm.delegitimize_address) (rtl); + rtl = targetm.delegitimize_address (rtl); switch (GET_CODE (rtl)) { @@ -8658,7 +8729,7 @@ loc_descriptor_from_tree (tree loc, int addressp) { dw_loc_descr_ref ret, ret1; int indirect_p = 0; - int unsignedp = TREE_UNSIGNED (TREE_TYPE (loc)); + int unsignedp = TYPE_UNSIGNED (TREE_TYPE (loc)); enum dwarf_location_atom op; /* ??? Most of the time we do not take proper care for sign/zero @@ -8670,7 +8741,6 @@ loc_descriptor_from_tree (tree loc, int addressp) case ERROR_MARK: return 0; - case WITH_RECORD_EXPR: case PLACEHOLDER_EXPR: /* This case involves extracting fields from an object to determine the position of other fields. We don't try to encode this here. The @@ -8681,6 +8751,13 @@ loc_descriptor_from_tree (tree loc, int addressp) case CALL_EXPR: return 0; + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: + /* There are no opcodes for these operations. */ + return 0; + case ADDR_EXPR: /* We can support this only if we can look through conversions and find an INDIRECT_EXPR. */ @@ -8837,7 +8914,7 @@ loc_descriptor_from_tree (tree loc, int addressp) mode = GET_MODE (rtl); rtl = XEXP (rtl, 0); - rtl = (*targetm.delegitimize_address) (rtl); + rtl = targetm.delegitimize_address (rtl); indirect_p = 1; ret = mem_loc_descriptor (rtl, mode, true); @@ -8911,28 +8988,28 @@ loc_descriptor_from_tree (tree loc, int addressp) goto do_binop; case LE_EXPR: - if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) + if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) return 0; op = DW_OP_le; goto do_binop; case GE_EXPR: - if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) + if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) return 0; op = DW_OP_ge; goto do_binop; case LT_EXPR: - if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) + if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) return 0; op = DW_OP_lt; goto do_binop; case GT_EXPR: - if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) + if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) return 0; op = DW_OP_gt; @@ -8977,11 +9054,17 @@ loc_descriptor_from_tree (tree loc, int addressp) add_loc_descr (&ret, new_loc_descr (op, 0, 0)); break; + case MIN_EXPR: case MAX_EXPR: - loc = build (COND_EXPR, TREE_TYPE (loc), - build (LT_EXPR, integer_type_node, - TREE_OPERAND (loc, 0), TREE_OPERAND (loc, 1)), - TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0)); + { + const enum tree_code code = + TREE_CODE (loc) == MIN_EXPR ? GT_EXPR : LT_EXPR; + + loc = build (COND_EXPR, TREE_TYPE (loc), + build (code, integer_type_node, + TREE_OPERAND (loc, 0), TREE_OPERAND (loc, 1)), + TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0)); + } /* ... fall through ... */ @@ -9616,7 +9699,7 @@ rtl_for_decl_location (tree decl) && TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)))) { - rtl = (*targetm.delegitimize_address) (rtl); + rtl = targetm.delegitimize_address (rtl); return rtl; } rtl = NULL_RTX; @@ -9723,7 +9806,7 @@ rtl_for_decl_location (tree decl) } if (rtl) - rtl = (*targetm.delegitimize_address) (rtl); + rtl = targetm.delegitimize_address (rtl); /* If we don't look past the constant pool, we risk emitting a reference to a constant pool entry that isn't referenced from @@ -10812,7 +10895,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) if (type_die->die_parent == NULL) add_child_die (scope_die_for (type, context_die), type_die); - for (link = TYPE_FIELDS (type); + for (link = TYPE_VALUES (type); link != NULL; link = TREE_CHAIN (link)) { dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link); @@ -10821,7 +10904,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) add_name_attribute (enum_die, IDENTIFIER_POINTER (TREE_PURPOSE (link))); - if (host_integerp (value, TREE_UNSIGNED (TREE_TYPE (value)))) + if (host_integerp (value, TYPE_UNSIGNED (TREE_TYPE (value)))) /* DWARF2 does not provide a way of indicating whether or not enumeration constants are signed or unsigned. GDB always assumes the values are signed, so we output all @@ -13004,7 +13087,7 @@ dwarf2out_source_line (unsigned int line, const char *filename) else if (DECL_SECTION_NAME (current_function_decl)) { dw_separate_line_info_ref line_info; - (*targetm.asm_out.internal_label) (asm_out_file, SEPARATE_LINE_CODE_LABEL, + targetm.asm_out.internal_label (asm_out_file, SEPARATE_LINE_CODE_LABEL, separate_line_info_table_in_use); /* Expand the line info table if necessary. */ @@ -13034,7 +13117,7 @@ dwarf2out_source_line (unsigned int line, const char *filename) { dw_line_info_ref line_info; - (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL, + targetm.asm_out.internal_label (asm_out_file, LINE_CODE_LABEL, line_info_table_in_use); /* Expand the line info table if necessary. */ @@ -13542,7 +13625,7 @@ dwarf2out_finish (const char *filename) /* Output a terminator label for the .text section. */ text_section (); - (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0); + targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0); /* Output the source line correspondence table. We must do this even if there is no line information. Otherwise, on an empty