X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdwarf2out.c;h=cfedd13bd2852b8b1a838b8d385172422d24ea98;hb=ac4ededf628466d520f6b6edbf15f14d2c1fe776;hp=55947932ddb0fa2f916d3b9ad3a40c4096471990;hpb=1b6ad37661ec49431e314afafa880338e1cfc872;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 55947932ddb..cfedd13bd28 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; @@ -3751,7 +3785,7 @@ static bool is_subrange_type (tree); static dw_die_ref subrange_type_die (tree, dw_die_ref); static dw_die_ref modified_type_die (tree, int, int, dw_die_ref); static int type_is_enum (tree); -static unsigned int reg_number (rtx); +static unsigned int dbx_reg_number (rtx); static dw_loc_descr_ref reg_loc_descriptor (rtx); static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int); static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx); @@ -5036,7 +5070,9 @@ is_fortran (void) { unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language); - return lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90; + return (lang == DW_LANG_Fortran77 + || lang == DW_LANG_Fortran90 + || lang == DW_LANG_Fortran95); } /* Return TRUE if the language is Java. */ @@ -6598,7 +6634,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 +6985,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 +7855,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 +7865,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 +8002,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 +8059,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 +8078,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. */ @@ -8169,10 +8242,10 @@ type_is_enum (tree type) return TREE_CODE (type) == ENUMERAL_TYPE; } -/* Return the register number described by a given RTL node. */ +/* Return the DBX register number described by a given RTL node. */ static unsigned int -reg_number (rtx rtl) +dbx_reg_number (rtx rtl) { unsigned regno = REGNO (rtl); @@ -8194,10 +8267,10 @@ reg_loc_descriptor (rtx rtl) if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER) return 0; - reg = reg_number (rtl); - regs = (*targetm.dwarf_register_span) (rtl); + reg = dbx_reg_number (rtl); + regs = targetm.dwarf_register_span (rtl); - if (hard_regno_nregs[reg][GET_MODE (rtl)] > 1 + if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs) return multiple_reg_loc_descriptor (rtl, regs); else @@ -8226,8 +8299,8 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs) unsigned reg; dw_loc_descr_ref loc_result = NULL; - reg = reg_number (rtl); - nregs = hard_regno_nregs[reg][GET_MODE (rtl)]; + reg = dbx_reg_number (rtl); + nregs = hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)]; /* Simple, contiguous registers. */ if (regs == NULL_RTX) @@ -8364,13 +8437,14 @@ static dw_loc_descr_ref mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg) { dw_loc_descr_ref mem_loc_result = NULL; + enum dwarf_location_atom op; /* Note that for a dynamically sized array, the location we will generate a description of here will be the lowest numbered location which is 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)) { @@ -8407,7 +8481,8 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg) memory) so DWARF consumers need to be aware of the subtle distinction between OP_REG and OP_BASEREG. */ if (REGNO (rtl) < FIRST_PSEUDO_REGISTER) - mem_loc_result = based_loc_descr (reg_number (rtl), 0, can_use_fbreg); + mem_loc_result = based_loc_descr (dbx_reg_number (rtl), 0, + can_use_fbreg); break; case MEM: @@ -8478,7 +8553,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg) case PLUS: plus: if (is_based_loc (rtl)) - mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)), + mem_loc_result = based_loc_descr (dbx_reg_number (XEXP (rtl, 0)), INTVAL (XEXP (rtl, 1)), can_use_fbreg); else @@ -8504,10 +8579,26 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg) } break; + /* If a pseudo-reg is optimized away, it is possible for it to + be replaced with a MEM containing a multiply or shift. */ case MULT: + op = DW_OP_mul; + goto do_binop; + + case ASHIFT: + op = DW_OP_shl; + goto do_binop; + + case ASHIFTRT: + op = DW_OP_shra; + goto do_binop; + + case LSHIFTRT: + op = DW_OP_shr; + goto do_binop; + + do_binop: { - /* If a pseudo-reg is optimized away, it is possible for it to - be replaced with a MEM containing a multiply. */ dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, can_use_fbreg); dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, @@ -8518,7 +8609,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg) mem_loc_result = op0; add_loc_descr (&mem_loc_result, op1); - add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0)); + add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0)); break; } @@ -8658,7 +8749,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 +8761,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 +8771,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. */ @@ -8734,6 +8831,7 @@ loc_descriptor_from_tree (tree loc, int addressp) /* Fall through. */ case PARM_DECL: + case RESULT_DECL: { rtx rtl = rtl_for_decl_location (loc); @@ -8837,7 +8935,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 +9009,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 +9075,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 ... */ @@ -9016,9 +9120,6 @@ loc_descriptor_from_tree (tree loc, int addressp) } break; - case EXPR_WITH_FILE_LOCATION: - return loc_descriptor_from_tree (EXPR_WFL_NODE (loc), addressp); - default: /* Leave front-end specific codes as simply unknown. This comes up, for instance, with the C STMT_EXPR. */ @@ -9595,10 +9696,7 @@ rtl_for_decl_location (tree decl) This happens (for example) for inlined-instances of inline function formal parameters which are never referenced. This really shouldn't be happening. All PARM_DECL nodes should get valid non-NULL - DECL_INCOMING_RTL values, but integrate.c doesn't currently generate these - values for inlined instances of inline function parameters, so when we see - such cases, we are just out-of-luck for the time being (until integrate.c - gets fixed). */ + DECL_INCOMING_RTL values. FIXME. */ /* Use DECL_RTL as the "location" unless we find something better. */ rtl = DECL_RTL_IF_SET (decl); @@ -9616,7 +9714,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; @@ -9673,6 +9771,25 @@ rtl_for_decl_location (tree decl) plus_constant (XEXP (rtl, 0), offset)); } } + else if (TREE_CODE (decl) == VAR_DECL + && rtl + && GET_CODE (rtl) == MEM + && GET_MODE (rtl) != TYPE_MODE (TREE_TYPE (decl)) + && BYTES_BIG_ENDIAN) + { + int rsize = GET_MODE_SIZE (GET_MODE (rtl)); + int dsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))); + + /* If a variable is declared "register" yet is smaller than + a register, then if we store the variable to memory, it + looks like we're storing a register-sized value, when in + fact we are not. We need to adjust the offset of the + storage location to reflect the actual value's bytes, + else gdb will not be able to display it. */ + if (rsize > dsize) + rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)), + plus_constant (XEXP (rtl, 0), rsize-dsize)); + } if (rtl != NULL_RTX) { @@ -9723,7 +9840,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 @@ -9755,7 +9872,8 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, if (TREE_CODE (decl) == ERROR_MARK) return; - else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL) + else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL + && TREE_CODE (decl) != RESULT_DECL) abort (); /* See if we possibly have multiple locations for this variable. */ @@ -10063,6 +10181,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b case VAR_DECL: case PARM_DECL: + case RESULT_DECL: { dw_die_ref decl_die = lookup_decl_die (bound); @@ -10812,7 +10931,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 +10940,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 @@ -11223,13 +11342,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg)); } -#if 0 - /* ??? This fails for nested inline functions, because context_display - is not part of the state saved/restored for inline functions. */ - if (current_function_needs_context) + if (cfun->static_chain_decl) add_AT_location_description (subr_die, DW_AT_static_link, - loc_descriptor (lookup_static_chain (decl))); -#endif + loc_descriptor_from_tree (cfun->static_chain_decl, 0)); } /* Now output descriptions of the arguments for this function. This gets @@ -11305,6 +11420,10 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) constructor function. */ if (! declaration && TREE_CODE (outer_scope) != ERROR_MARK) { + /* Emit a DW_TAG_variable DIE for a named return value. */ + if (DECL_NAME (DECL_RESULT (decl))) + gen_decl_die (DECL_RESULT (decl), subr_die); + current_function_has_inlines = 0; decls_for_scope (outer_scope, subr_die, 0); @@ -11649,6 +11768,8 @@ gen_compile_unit_die (const char *filename) language = DW_LANG_Ada95; else if (strcmp (language_string, "GNU F77") == 0) language = DW_LANG_Fortran77; + else if (strcmp (language_string, "GNU F95") == 0) + language = DW_LANG_Fortran95; else if (strcmp (language_string, "GNU Pascal") == 0) language = DW_LANG_Pascal83; else if (strcmp (language_string, "GNU Java") == 0) @@ -12458,6 +12579,14 @@ gen_decl_die (tree decl, dw_die_ref context_die) && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl))) break; +#if 0 + /* FIXME */ + /* This doesn't work because the C frontend sets DECL_ABSTRACT_ORIGIN + on local redeclarations of global functions. That seems broken. */ + if (current_function_decl != decl) + /* This is only a declaration. */; +#endif + /* If we're emitting a clone, emit info for the abstract instance. */ if (DECL_ORIGIN (decl) != decl) dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl)); @@ -12531,6 +12660,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) break; case VAR_DECL: + case RESULT_DECL: /* If we are in terse mode, don't generate any DIEs to represent any variable declarations or definitions. */ if (debug_info_level <= DINFO_LEVEL_TERSE) @@ -12661,8 +12791,8 @@ dwarf2out_imported_module_or_decl (tree decl, tree context) else scope_die = force_decl_die (context); - /* For TYPE_DECL, lookup TREE_TYPE. */ - if (TREE_CODE (decl) == TYPE_DECL) + /* For TYPE_DECL or CONST_DECL, lookup TREE_TYPE. */ + if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL) at_import_die = force_type_die (TREE_TYPE (decl)); else at_import_die = force_decl_die (decl); @@ -13004,7 +13134,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 +13164,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 +13672,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