diff options
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 659b119f4bd..7ce80506fdc 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1,5 +1,6 @@ /* Output Dwarf2 format symbol table information from the GNU C compiler. - Copyright (C) 1992, 93, 95-98, 1999 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000 Free Software + Foundation, Inc. Contributed by Gary Funck (gary@intrepid.com). Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com). Extensively modified by Jason Merrill (jason@cygnus.com). @@ -719,6 +720,8 @@ dwarf_cfi_name (cfi_opc) return "DW_CFA_GNU_window_save"; case DW_CFA_GNU_args_size: return "DW_CFA_GNU_args_size"; + case DW_CFA_GNU_negative_offset_extended: + return "DW_CFA_GNU_negative_offset_extended"; default: return "DW_CFA_<unknown>"; @@ -948,7 +951,10 @@ reg_save (label, reg, sreg, offset) offset /= DWARF_CIE_DATA_ALIGNMENT; if (offset < 0) - abort (); + { + cfi->dw_cfi_opc = DW_CFA_GNU_negative_offset_extended; + offset = -offset; + } cfi->dw_cfi_oprnd2.dw_cfi_offset = offset; } else @@ -1635,6 +1641,7 @@ output_cfi (cfi, fde) break; #endif case DW_CFA_offset_extended: + case DW_CFA_GNU_negative_offset_extended: case DW_CFA_def_cfa: output_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num); fputc ('\n', asm_out_file); @@ -2426,6 +2433,22 @@ static unsigned pending_types; be enough for most typical programs. */ #define PENDING_TYPES_INCREMENT 64 +/* A pointer to the base of a list of incomplete types which might be + completed at some later time. */ + +static tree *incomplete_types_list; + +/* Number of elements currently allocated for the incomplete_types_list. */ +static unsigned incomplete_types_allocated; + +/* Number of elements of incomplete_types_list currently in use. */ +static unsigned incomplete_types; + +/* Size (in elements) of increments by which we may expand the incomplete + types list. Actually, a single hunk of space of this size should + be enough for most typical programs. */ +#define INCOMPLETE_TYPES_INCREMENT 64 + /* Record whether the function being analyzed contains inlined functions. */ static int current_function_has_inlines; #if 0 && defined (MIPS_DEBUGGING_INFO) @@ -2728,8 +2751,10 @@ static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; dyn_string_append (STR, NAME + 1); \ else \ { \ + char *newstr; \ + STRIP_NAME_ENCODING (newstr, NAME); \ dyn_string_append (STR, user_label_prefix); \ - dyn_string_append (STR, NAME); \ + dyn_string_append (STR, newstr); \ } \ } \ while (0) @@ -5117,6 +5142,11 @@ output_abbrev_section () fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP); } + + /* We need to properly terminate the abbrev table for this + compilation unit, as per the standard, and not rely on + workarounds in e.g. gdb. */ + fprintf (asm_out_file, "\t%s\t0\n", ASM_BYTE_OP); } /* Output location description stack opcode's operands (if any). */ @@ -7165,7 +7195,8 @@ add_location_or_const_value_attribute (die, decl) rtl = DECL_INCOMING_RTL (decl); else if (! BYTES_BIG_ENDIAN && TREE_CODE (declared_type) == INTEGER_TYPE - && TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type)) + && (GET_MODE_SIZE (TYPE_MODE (declared_type)) + <= GET_MODE_SIZE (TYPE_MODE (passed_type)))) rtl = DECL_INCOMING_RTL (decl); } @@ -8033,6 +8064,39 @@ output_pending_types_for_scope (context_die) } } +/* Remember a type in the incomplete_types_list. */ + +static void +add_incomplete_type (type) + tree type; +{ + if (incomplete_types == incomplete_types_allocated) + { + incomplete_types_allocated += INCOMPLETE_TYPES_INCREMENT; + incomplete_types_list + = (tree *) xrealloc (incomplete_types_list, + sizeof (tree) * incomplete_types_allocated); + } + + incomplete_types_list[incomplete_types++] = type; +} + +/* Walk through the list of incomplete types again, trying once more to + emit full debugging info for them. */ + +static void +retry_incomplete_types () +{ + register tree type; + + while (incomplete_types) + { + --incomplete_types; + type = incomplete_types_list[incomplete_types]; + gen_type_die (type, comp_unit_die); + } +} + /* Generate a DIE to represent an inlined instance of an enumeration type. */ static void @@ -9024,7 +9088,13 @@ gen_struct_or_union_type_die (type, context_die) } } else - add_AT_flag (type_die, DW_AT_declaration, 1); + { + add_AT_flag (type_die, DW_AT_declaration, 1); + + /* We can't do this for function-local types, and we don't need to. */ + if (TREE_PERMANENT (type)) + add_incomplete_type (type); + } } /* Generate a DIE for a subroutine _type_. */ @@ -9993,6 +10063,10 @@ dwarf2out_finish () free (node); } + /* Walk through the list of incomplete types again, trying once more to + emit full debugging info for them. */ + retry_incomplete_types (); + /* Traverse the DIE tree and add sibling attributes to those DIE's that have children. */ add_sibling_attributes (comp_unit_die); |