From c90bf86c4c2d2f220539f0c8764c58ff8e15bbc5 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 23 Nov 1999 01:50:36 +0000 Subject: [PATCH] * dwarf2out.c (die_struct): Remove die_attr_last and die_child_last. (add_dwarf_attr, add_child_die): Just push onto the front. (reverse_die_lists): New fn. (add_sibling_attributes): Use it. (push_decl_scope): Reorganize. (gen_struct_or_union_type_die): Don't add a DW_AT_containing_type that points to ourself. (add_name_and_src_coords_attributes): Don't set file and line for an artificial decl. (gen_subprogram_die): An artificial function doesn't need to match file and line. (gen_compile_unit_die): Return the generated die. Only add AT_comp_dir if the filename is relative. (remove_AT): Simplify loop. Also free string values. (output_die): A DIE ref can't be null. (output_value_format, value_format): Take a dw_attr_ref. (dwarf_last_decl, is_extern_subr_die, sibling_offset): Remove. (AT_class, AT_flag, AT_int, AT_unsigned, AT_string, AT_ref, AT_loc, AT_addr, AT_lbl): New fns. (various): Use them. (various): Constify. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30624 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 24 +++ gcc/dwarf2out.c | 566 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 306 insertions(+), 284 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 82f73ad..10f3f62 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +1999-11-22 Jason Merrill + + * dwarf2out.c (die_struct): Remove die_attr_last and die_child_last. + (add_dwarf_attr, add_child_die): Just push onto the front. + (reverse_die_lists): New fn. + (add_sibling_attributes): Use it. + (push_decl_scope): Reorganize. + (gen_struct_or_union_type_die): Don't add a DW_AT_containing_type + that points to ourself. + (add_name_and_src_coords_attributes): Don't set file and line for + an artificial decl. + (gen_subprogram_die): An artificial function doesn't need to match + file and line. + (gen_compile_unit_die): Return the generated die. Only add + AT_comp_dir if the filename is relative. + (remove_AT): Simplify loop. Also free string values. + (output_die): A DIE ref can't be null. + (output_value_format, value_format): Take a dw_attr_ref. + (dwarf_last_decl, is_extern_subr_die, sibling_offset): Remove. + (AT_class, AT_flag, AT_int, AT_unsigned, AT_string, AT_ref, AT_loc, + AT_addr, AT_lbl): New fns. + (various): Use them. + (various): Constify. + Mon Nov 22 23:53:50 1999 J"orn Rennecke * combine.c (combine_simplify_rtx): When handling a SUBREG, diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 160b801..884a518 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -21,10 +21,7 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* TODO: Implement .debug_str handling. - Share .debug_str entries via comdat. - Use compact DIE references; we don't always need a 4-byte reference. - (maybe; would it be worth the larger abbrev section?) +/* TODO: Implement .debug_str handling, and share entries somehow. Eliminate duplicates by putting common info in a separate section to be collected by the linker and referring to it with DW_FORM_ref_addr. @@ -68,6 +65,10 @@ Boston, MA 02111-1307, USA. */ # define assert(e) do { if (! (e)) abort (); } while (0) #endif +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + /* Decide whether we want to emit frame unwind information for the current translation unit. */ @@ -2073,10 +2074,8 @@ typedef struct die_struct { enum dwarf_tag die_tag; dw_attr_ref die_attr; - dw_attr_ref die_attr_last; dw_die_ref die_parent; dw_die_ref die_child; - dw_die_ref die_child_last; dw_die_ref die_sib; dw_offset die_offset; unsigned long die_abbrev; @@ -2362,12 +2361,6 @@ static int current_function_has_inlines; static int comp_unit_has_inlines; #endif -/* A pointer to the ..._DECL node which we have most recently been working - on. We keep this around just in case something about it looks screwy and - we want to tell the user what the source coordinates for the actual - declaration are. */ -static tree dwarf_last_decl; - /* Forward declarations for functions defined in this file. */ static void addr_const_to_string PROTO((dyn_string_t, rtx)); @@ -2418,12 +2411,11 @@ static void add_AT_lbl_id PROTO((dw_die_ref, enum dwarf_attribute, char *)); static void add_AT_lbl_offset PROTO((dw_die_ref, enum dwarf_attribute, char *)); -static int is_extern_subr_die PROTO((dw_die_ref)); static dw_attr_ref get_AT PROTO((dw_die_ref, enum dwarf_attribute)); -static char *get_AT_low_pc PROTO((dw_die_ref)); -static char *get_AT_hi_pc PROTO((dw_die_ref)); -static char *get_AT_string PROTO((dw_die_ref, +static const char *get_AT_low_pc PROTO((dw_die_ref)); +static const char *get_AT_hi_pc PROTO((dw_die_ref)); +static const char *get_AT_string PROTO((dw_die_ref, enum dwarf_attribute)); static int get_AT_flag PROTO((dw_die_ref, enum dwarf_attribute)); @@ -2449,7 +2441,7 @@ static void print_die PROTO((dw_die_ref, FILE *)); static void print_dwarf_line_table PROTO((FILE *)); static void add_sibling_attributes PROTO((dw_die_ref)); static void build_abbrev_table PROTO((dw_die_ref)); -static unsigned long size_of_string PROTO((char *)); +static unsigned long size_of_string PROTO((const char *)); static unsigned long size_of_loc_descr PROTO((dw_loc_descr_ref)); static unsigned long size_of_locs PROTO((dw_loc_descr_ref)); static int constant_size PROTO((long unsigned)); @@ -2458,11 +2450,10 @@ static void calc_die_sizes PROTO((dw_die_ref)); static unsigned long size_of_line_prolog PROTO((void)); static unsigned long size_of_pubnames PROTO((void)); static unsigned long size_of_aranges PROTO((void)); -static enum dwarf_form value_format PROTO((dw_val_ref)); -static void output_value_format PROTO((dw_val_ref)); +static enum dwarf_form value_format PROTO((dw_attr_ref)); +static void output_value_format PROTO((dw_attr_ref)); static void output_abbrev_section PROTO((void)); static void output_loc_operands PROTO((dw_loc_descr_ref)); -static unsigned long sibling_offset PROTO((dw_die_ref)); static void output_die PROTO((dw_die_ref)); static void output_compilation_unit_header PROTO((void)); static const char *dwarf2_name PROTO((tree, int)); @@ -2536,7 +2527,7 @@ static void gen_lexical_block_die PROTO((tree, dw_die_ref, int)); static void gen_inlined_subroutine_die PROTO((tree, dw_die_ref, int)); static void gen_field_die PROTO((tree, dw_die_ref)); static void gen_ptr_to_mbr_type_die PROTO((tree, dw_die_ref)); -static void gen_compile_unit_die PROTO((char *)); +static dw_die_ref gen_compile_unit_die PROTO((const char *)); static void gen_string_type_die PROTO((tree, dw_die_ref)); static void gen_inheritance_die PROTO((tree, dw_die_ref)); static void gen_member_die PROTO((tree, dw_die_ref)); @@ -2672,11 +2663,11 @@ static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; /* We allow a language front-end to designate a function that is to be called to "demangle" any name before it it put into a DIE. */ -static char *(*demangle_name_func) PROTO((char *)); +static const char *(*demangle_name_func) PROTO((const char *)); void dwarf2out_set_demangle_name_func (func) - char *(*func) PROTO((char *)); + const char *(*func) PROTO((const char *)); { demangle_name_func = func; } @@ -3615,7 +3606,8 @@ decl_class_context (decl) return context; } -/* Add an attribute/value pair to a DIE */ +/* Add an attribute/value pair to a DIE. We build the lists up in reverse + addition order, and correct that in add_sibling_attributes. */ static inline void add_dwarf_attr (die, attr) @@ -3624,19 +3616,18 @@ add_dwarf_attr (die, attr) { if (die != NULL && attr != NULL) { - if (die->die_attr == NULL) - { - die->die_attr = attr; - die->die_attr_last = attr; - } - else - { - die->die_attr_last->dw_attr_next = attr; - die->die_attr_last = attr; - } + attr->dw_attr_next = die->die_attr; + die->die_attr = attr; } } +static inline dw_val_class +AT_class (a) + dw_attr_ref a; +{ + return a->dw_attr_val.val_class; +} + /* Add a flag value attribute to a DIE. */ static inline void @@ -3654,6 +3645,16 @@ add_AT_flag (die, attr_kind, flag) add_dwarf_attr (die, attr); } +static inline unsigned +AT_flag (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_flag) + return a->dw_attr_val.v.val_flag; + + return 0; +} + /* Add a signed integer attribute value to a DIE. */ static inline void @@ -3671,6 +3672,16 @@ add_AT_int (die, attr_kind, int_val) add_dwarf_attr (die, attr); } +static inline long int +AT_int (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_const) + return a->dw_attr_val.v.val_int; + + return 0; +} + /* Add an unsigned integer attribute value to a DIE. */ static inline void @@ -3688,6 +3699,16 @@ add_AT_unsigned (die, attr_kind, unsigned_val) add_dwarf_attr (die, attr); } +static inline unsigned long +AT_unsigned (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_unsigned_const) + return a->dw_attr_val.v.val_unsigned; + + return 0; +} + /* Add an unsigned double integer attribute value to a DIE. */ static inline void @@ -3743,6 +3764,16 @@ add_AT_string (die, attr_kind, str) add_dwarf_attr (die, attr); } +static inline const char * +AT_string (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_str) + return a->dw_attr_val.v.val_str; + + return NULL; +} + /* Add a DIE reference attribute value to a DIE. */ static inline void @@ -3760,6 +3791,16 @@ add_AT_die_ref (die, attr_kind, targ_die) add_dwarf_attr (die, attr); } +static inline dw_die_ref +AT_ref (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_die_ref) + return a->dw_attr_val.v.val_die_ref; + + return NULL; +} + /* Add an FDE reference attribute value to a DIE. */ static inline void @@ -3794,6 +3835,16 @@ add_AT_loc (die, attr_kind, loc) add_dwarf_attr (die, attr); } +static inline dw_loc_descr_ref +AT_loc (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_loc) + return a->dw_attr_val.v.val_loc; + + return NULL; +} + /* Add an address constant attribute value to a DIE. */ static inline void @@ -3811,6 +3862,16 @@ add_AT_addr (die, attr_kind, addr) add_dwarf_attr (die, attr); } +static inline const char * +AT_addr (a) + register dw_attr_ref a; +{ + if (a && AT_class (a) == dw_val_class_addr) + return a->dw_attr_val.v.val_addr; + + return NULL; +} + /* Add a label identifier attribute value to a DIE. */ static inline void @@ -3841,37 +3902,20 @@ add_AT_lbl_offset (die, attr_kind, label) attr->dw_attr_next = NULL; attr->dw_attr = attr_kind; attr->dw_attr_val.val_class = dw_val_class_lbl_offset; - attr->dw_attr_val.v.val_lbl_id = label; + attr->dw_attr_val.v.val_lbl_id = xstrdup (label); add_dwarf_attr (die, attr); } -/* Test if die refers to an external subroutine. */ - -static inline int -is_extern_subr_die (die) - register dw_die_ref die; +static inline const char * +AT_lbl (a) + register dw_attr_ref a; { - register dw_attr_ref a; - register int is_subr = FALSE; - register int is_extern = FALSE; - - if (die != NULL && die->die_tag == DW_TAG_subprogram) - { - is_subr = TRUE; - for (a = die->die_attr; a != NULL; a = a->dw_attr_next) - { - if (a->dw_attr == DW_AT_external - && a->dw_attr_val.val_class == dw_val_class_flag - && a->dw_attr_val.v.val_flag != 0) - { - is_extern = TRUE; - break; - } - } - } + if (a && (AT_class (a) == dw_val_class_lbl_id + || AT_class (a) == dw_val_class_lbl_offset)) + return a->dw_attr_val.v.val_lbl_id; - return is_subr && is_extern; + return NULL; } /* Get the attribute of type attr_kind. */ @@ -3893,7 +3937,7 @@ get_AT (die, attr_kind) if (a->dw_attr == DW_AT_specification || a->dw_attr == DW_AT_abstract_origin) - spec = a->dw_attr_val.v.val_die_ref; + spec = AT_ref (a); } if (spec) @@ -3908,16 +3952,12 @@ get_AT (die, attr_kind) either not prsent, or if it cannot be represented as an assembler label identifier. */ -static inline char * +static inline const char * get_AT_low_pc (die) register dw_die_ref die; { register dw_attr_ref a = get_AT (die, DW_AT_low_pc); - - if (a && a->dw_attr_val.val_class == dw_val_class_lbl_id) - return a->dw_attr_val.v.val_lbl_id; - - return NULL; + return AT_lbl (a); } /* Return the "high pc" attribute value, typically associated with @@ -3925,32 +3965,24 @@ get_AT_low_pc (die) either not prsent, or if it cannot be represented as an assembler label identifier. */ -static inline char * +static inline const char * get_AT_hi_pc (die) register dw_die_ref die; { register dw_attr_ref a = get_AT (die, DW_AT_high_pc); - - if (a && a->dw_attr_val.val_class == dw_val_class_lbl_id) - return a->dw_attr_val.v.val_lbl_id; - - return NULL; + return AT_lbl (a); } /* Return the value of the string attribute designated by ATTR_KIND, or NULL if it is not present. */ -static inline char * +static inline const char * get_AT_string (die, attr_kind) register dw_die_ref die; register enum dwarf_attribute attr_kind; { register dw_attr_ref a = get_AT (die, attr_kind); - - if (a && a->dw_attr_val.val_class == dw_val_class_str) - return a->dw_attr_val.v.val_str; - - return NULL; + return AT_string (a); } /* Return the value of the flag attribute designated by ATTR_KIND, or -1 @@ -3962,11 +3994,7 @@ get_AT_flag (die, attr_kind) register enum dwarf_attribute attr_kind; { register dw_attr_ref a = get_AT (die, attr_kind); - - if (a && a->dw_attr_val.val_class == dw_val_class_flag) - return a->dw_attr_val.v.val_flag; - - return -1; + return AT_flag (a); } /* Return the value of the unsigned attribute designated by ATTR_KIND, or 0 @@ -3978,11 +4006,16 @@ get_AT_unsigned (die, attr_kind) register enum dwarf_attribute attr_kind; { register dw_attr_ref a = get_AT (die, attr_kind); + return AT_unsigned (a); +} - if (a && a->dw_attr_val.val_class == dw_val_class_unsigned_const) - return a->dw_attr_val.v.val_unsigned; - - return 0; +static inline dw_die_ref +get_AT_ref (die, attr_kind) + dw_die_ref die; + register enum dwarf_attribute attr_kind; +{ + register dw_attr_ref a = get_AT (die, attr_kind); + return AT_ref (a); } static inline int @@ -4009,35 +4042,36 @@ remove_AT (die, attr_kind) register dw_die_ref die; register enum dwarf_attribute attr_kind; { - register dw_attr_ref a; + register dw_attr_ref *p; register dw_attr_ref removed = NULL; if (die != NULL) { - if (die->die_attr->dw_attr == attr_kind) - { - removed = die->die_attr; - if (die->die_attr_last == die->die_attr) - die->die_attr_last = NULL; - - die->die_attr = die->die_attr->dw_attr_next; - } + for (p = &(die->die_attr); *p; p = &((*p)->dw_attr_next)) + if ((*p)->dw_attr == attr_kind) + { + removed = *p; + *p = (*p)->dw_attr_next; + break; + } - else - for (a = die->die_attr; a->dw_attr_next != NULL; - a = a->dw_attr_next) - if (a->dw_attr_next->dw_attr == attr_kind) + if (removed != 0) + { + switch (AT_class (removed)) { - removed = a->dw_attr_next; - if (die->die_attr_last == a->dw_attr_next) - die->die_attr_last = a; + case dw_val_class_addr: + case dw_val_class_str: + case dw_val_class_lbl_id: + case dw_val_class_lbl_offset: + free (removed->dw_attr_val.v.val_str); + break; - a->dw_attr_next = a->dw_attr_next->dw_attr_next; + default: break; } - if (removed != 0) - free (removed); + free (removed); + } } } @@ -4050,7 +4084,6 @@ remove_children (die) register dw_die_ref child_die = die->die_child; die->die_child = NULL; - die->die_child_last = NULL; while (child_die != NULL) { @@ -4071,7 +4104,8 @@ remove_children (die) } } -/* Add a child DIE below its parent. */ +/* Add a child DIE below its parent. We build the lists up in reverse + addition order, and correct that in add_sibling_attributes. */ static inline void add_child_die (die, child_die) @@ -4083,18 +4117,8 @@ add_child_die (die, child_die) if (die == child_die) abort (); child_die->die_parent = die; - child_die->die_sib = NULL; - - if (die->die_child == NULL) - { - die->die_child = child_die; - die->die_child_last = child_die; - } - else - { - die->die_child_last->die_sib = child_die; - die->die_child_last = child_die; - } + child_die->die_sib = die->die_child; + die->die_child = child_die; } } @@ -4113,9 +4137,7 @@ new_die (tag_value, parent_die) die->die_child = NULL; die->die_parent = NULL; die->die_sib = NULL; - die->die_child_last = NULL; die->die_attr = NULL; - die->die_attr_last = NULL; if (parent_die != NULL) add_child_die (parent_die, die); @@ -4271,7 +4293,7 @@ print_die (die, outfile) print_spaces (outfile); fprintf (outfile, " %s: ", dwarf_attr_name (a->dw_attr)); - switch (a->dw_attr_val.val_class) + switch (AT_class (a)) { case dw_val_class_addr: fprintf (outfile, "address"); @@ -4280,10 +4302,10 @@ print_die (die, outfile) fprintf (outfile, "location descriptor"); break; case dw_val_class_const: - fprintf (outfile, "%ld", a->dw_attr_val.v.val_int); + fprintf (outfile, "%ld", AT_int (a)); break; case dw_val_class_unsigned_const: - fprintf (outfile, "%lu", a->dw_attr_val.v.val_unsigned); + fprintf (outfile, "%lu", AT_unsigned (a)); break; case dw_val_class_long_long: fprintf (outfile, "constant (%lu,%lu)", @@ -4294,22 +4316,21 @@ print_die (die, outfile) fprintf (outfile, "floating-point constant"); break; case dw_val_class_flag: - fprintf (outfile, "%u", a->dw_attr_val.v.val_flag); + fprintf (outfile, "%u", AT_flag (a)); break; case dw_val_class_die_ref: - if (a->dw_attr_val.v.val_die_ref != NULL) - fprintf (outfile, "die -> %lu", - a->dw_attr_val.v.val_die_ref->die_offset); + if (AT_ref (a) != NULL) + fprintf (outfile, "die -> %lu", AT_ref (a)->die_offset); else fprintf (outfile, "die -> "); break; case dw_val_class_lbl_id: case dw_val_class_lbl_offset: - fprintf (outfile, "label: %s", a->dw_attr_val.v.val_lbl_id); + fprintf (outfile, "label: %s", AT_lbl (a)); break; case dw_val_class_str: - if (a->dw_attr_val.v.val_str != NULL) - fprintf (outfile, "\"%s\"", a->dw_attr_val.v.val_str); + if (AT_string (a) != NULL) + fprintf (outfile, "\"%s\"", AT_string (a)); else fprintf (outfile, ""); break; @@ -4374,31 +4395,50 @@ debug_dwarf () print_dwarf_line_table (stderr); } -/* Traverse the DIE, and add a sibling attribute if it may have the - effect of speeding up access to siblings. To save some space, - avoid generating sibling attributes for DIE's without children. */ +/* We build up the lists of children and attributes by pushing new ones + onto the beginning of the list. Reverse the lists for DIE so that + they are in order of addition. */ static void -add_sibling_attributes(die) +reverse_die_lists (die) register dw_die_ref die; { - register dw_die_ref c; - register dw_attr_ref attr; - if (die != comp_unit_die && die->die_child != NULL) - { - attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node)); - attr->dw_attr_next = NULL; - attr->dw_attr = DW_AT_sibling; - attr->dw_attr_val.val_class = dw_val_class_die_ref; - attr->dw_attr_val.v.val_die_ref = die->die_sib; + register dw_die_ref c, cp, cn; + register dw_attr_ref a, ap, an; - /* Add the sibling link to the front of the attribute list. */ - attr->dw_attr_next = die->die_attr; - if (die->die_attr == NULL) - die->die_attr_last = attr; + for (a = die->die_attr, ap = 0; a; a = an) + { + an = a->dw_attr_next; + a->dw_attr_next = ap; + ap = a; + } + die->die_attr = ap; - die->die_attr = attr; + for (c = die->die_child, cp = 0; c; c = cn) + { + cn = c->die_sib; + c->die_sib = cp; + cp = c; } + die->die_child = cp; +} + +/* Traverse the DIE, reverse its lists of attributes and children, and + add a sibling attribute if it may have the effect of speeding up + access to siblings. To save some space, avoid generating sibling + attributes for DIE's without children. */ + +static void +add_sibling_attributes (die) + register dw_die_ref die; +{ + register dw_die_ref c; + + reverse_die_lists (die); + + if (die != comp_unit_die && die->die_sib && die->die_child != NULL) + /* Add the sibling link to the front of the attribute list. */ + add_AT_die_ref (die, DW_AT_sibling, die->die_sib); for (c = die->die_child; c != NULL; c = c->die_sib) add_sibling_attributes (c); @@ -4432,8 +4472,7 @@ build_abbrev_table (die) while (a_attr != NULL && d_attr != NULL) { if ((a_attr->dw_attr != d_attr->dw_attr) - || (value_format (&a_attr->dw_attr_val) - != value_format (&d_attr->dw_attr_val))) + || (value_format (a_attr) != value_format (d_attr))) break; a_attr = a_attr->dw_attr_next; @@ -4478,7 +4517,7 @@ build_abbrev_table (die) static unsigned long size_of_string (str) - register char *str; + register const char *str; { return strlen (str) + 1; } @@ -4632,15 +4671,14 @@ size_of_die (die) size += size_of_uleb128 (die->die_abbrev); for (a = die->die_attr; a != NULL; a = a->dw_attr_next) { - switch (a->dw_attr_val.val_class) + switch (AT_class (a)) { case dw_val_class_addr: size += PTR_SIZE; break; case dw_val_class_loc: { - register unsigned long lsize - = size_of_locs (a->dw_attr_val.v.val_loc); + register unsigned long lsize = size_of_locs (AT_loc (a)); /* Block length. */ size += constant_size (lsize); @@ -4651,7 +4689,7 @@ size_of_die (die) size += 4; break; case dw_val_class_unsigned_const: - size += constant_size (a->dw_attr_val.v.val_unsigned); + size += constant_size (AT_unsigned (a)); break; case dw_val_class_long_long: size += 1 + 8; /* block */ @@ -4675,7 +4713,7 @@ size_of_die (die) size += DWARF_OFFSET_SIZE; break; case dw_val_class_str: - size += size_of_string (a->dw_attr_val.v.val_str); + size += size_of_string (AT_string (a)); break; default: abort (); @@ -4787,15 +4825,15 @@ size_of_aranges () /* Select the encoding of an attribute value. */ static enum dwarf_form -value_format (v) - dw_val_ref v; +value_format (a) + dw_attr_ref a; { - switch (v->val_class) + switch (a->dw_attr_val.val_class) { case dw_val_class_addr: return DW_FORM_addr; case dw_val_class_loc: - switch (constant_size (size_of_locs (v->v.val_loc))) + switch (constant_size (size_of_locs (AT_loc (a)))) { case 1: return DW_FORM_block1; @@ -4807,7 +4845,7 @@ value_format (v) case dw_val_class_const: return DW_FORM_data4; case dw_val_class_unsigned_const: - switch (constant_size (v->v.val_unsigned)) + switch (constant_size (AT_unsigned (a))) { case 1: return DW_FORM_data1; @@ -4844,10 +4882,10 @@ value_format (v) /* Output the encoding of an attribute value. */ static void -output_value_format (v) - dw_val_ref v; +output_value_format (a) + dw_attr_ref a; { - enum dwarf_form form = value_format (v); + enum dwarf_form form = value_format (a); output_uleb128 (form); if (flag_debug_asm) @@ -4900,7 +4938,7 @@ output_abbrev_section () dwarf_attr_name (a_attr->dw_attr)); fputc ('\n', asm_out_file); - output_value_format (&a_attr->dw_attr_val); + output_value_format (a_attr); } fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP); @@ -5029,22 +5067,6 @@ output_loc_operands (loc) } } -/* Compute the offset of a sibling. */ - -static unsigned long -sibling_offset (die) - dw_die_ref die; -{ - unsigned long offset; - - if (die->die_child_last == NULL) - offset = die->die_offset + size_of_die (die); - else - offset = sibling_offset (die->die_child_last) + 1; - - return offset; -} - /* Output the DIE and its attributes. Called recursively to generate the definitions of each child DIE. */ @@ -5054,7 +5076,6 @@ output_die (die) { register dw_attr_ref a; register dw_die_ref c; - register unsigned long ref_offset; register unsigned long size; register dw_loc_descr_ref loc; @@ -5067,15 +5088,14 @@ output_die (die) for (a = die->die_attr; a != NULL; a = a->dw_attr_next) { - switch (a->dw_attr_val.val_class) + switch (AT_class (a)) { case dw_val_class_addr: - ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, - a->dw_attr_val.v.val_addr); + ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, AT_addr (a)); break; case dw_val_class_loc: - size = size_of_locs (a->dw_attr_val.v.val_loc); + size = size_of_locs (AT_loc (a)); /* Output the block length for this list of location operations. */ switch (constant_size (size)) @@ -5095,8 +5115,7 @@ output_die (die) ASM_COMMENT_START, dwarf_attr_name (a->dw_attr)); fputc ('\n', asm_out_file); - for (loc = a->dw_attr_val.v.val_loc; loc != NULL; - loc = loc->dw_loc_next) + for (loc = AT_loc (a); loc != NULL; loc = loc->dw_loc_next) { /* Output the opcode. */ ASM_OUTPUT_DWARF_DATA1 (asm_out_file, loc->dw_loc_opc); @@ -5112,23 +5131,20 @@ output_die (die) break; case dw_val_class_const: - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, a->dw_attr_val.v.val_int); + ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_int (a)); break; case dw_val_class_unsigned_const: - switch (constant_size (a->dw_attr_val.v.val_unsigned)) + switch (constant_size (AT_unsigned (a))) { case 1: - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, - a->dw_attr_val.v.val_unsigned); + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, AT_unsigned (a)); break; case 2: - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, - a->dw_attr_val.v.val_unsigned); + ASM_OUTPUT_DWARF_DATA2 (asm_out_file, AT_unsigned (a)); break; case 4: - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, - a->dw_attr_val.v.val_unsigned); + ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_unsigned (a)); break; case 8: ASM_OUTPUT_DWARF_DATA8 (asm_out_file, @@ -5182,18 +5198,11 @@ output_die (die) } case dw_val_class_flag: - ASM_OUTPUT_DWARF_DATA1 (asm_out_file, a->dw_attr_val.v.val_flag); + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, AT_flag (a)); break; case dw_val_class_die_ref: - if (a->dw_attr_val.v.val_die_ref != NULL) - ref_offset = a->dw_attr_val.v.val_die_ref->die_offset; - else if (a->dw_attr == DW_AT_sibling) - ref_offset = sibling_offset(die); - else - abort (); - - ASM_OUTPUT_DWARF_DATA (asm_out_file, ref_offset); + ASM_OUTPUT_DWARF_DATA (asm_out_file, AT_ref (a)->die_offset); break; case dw_val_class_fde_ref: @@ -5207,29 +5216,28 @@ output_die (die) break; case dw_val_class_lbl_id: - ASM_OUTPUT_DWARF_ADDR (asm_out_file, a->dw_attr_val.v.val_lbl_id); + ASM_OUTPUT_DWARF_ADDR (asm_out_file, AT_lbl (a)); break; case dw_val_class_lbl_offset: - ASM_OUTPUT_DWARF_OFFSET (asm_out_file, a->dw_attr_val.v.val_lbl_id); + ASM_OUTPUT_DWARF_OFFSET (asm_out_file, AT_lbl (a)); break; case dw_val_class_str: if (flag_debug_asm) - ASM_OUTPUT_DWARF_STRING (asm_out_file, a->dw_attr_val.v.val_str); + ASM_OUTPUT_DWARF_STRING (asm_out_file, AT_string (a)); else - ASM_OUTPUT_ASCII (asm_out_file, - a->dw_attr_val.v.val_str, - (int) strlen (a->dw_attr_val.v.val_str) + 1); + ASM_OUTPUT_ASCII (asm_out_file, AT_string (a), + (int) strlen (AT_string (a)) + 1); break; default: abort (); } - if (a->dw_attr_val.val_class != dw_val_class_loc - && a->dw_attr_val.val_class != dw_val_class_long_long - && a->dw_attr_val.val_class != dw_val_class_float) + if (AT_class (a) != dw_val_class_loc + && AT_class (a) != dw_val_class_long_long + && AT_class (a) != dw_val_class_float) { if (flag_debug_asm) fprintf (asm_out_file, "\t%s %s", @@ -5482,10 +5490,10 @@ output_aranges () dw_attr_ref a = get_AT (die, DW_AT_location); dw_loc_descr_ref loc; - if (! a || a->dw_attr_val.val_class != dw_val_class_loc) + if (! a || AT_class (a) != dw_val_class_loc) abort (); - loc = a->dw_attr_val.v.val_loc; + loc = AT_loc (a); if (loc->dw_loc_opc != DW_OP_addr) abort (); @@ -7505,7 +7513,8 @@ add_name_and_src_coords_attributes (die, decl) if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL) { add_name_attribute (die, dwarf2_name (decl, 0)); - add_src_coords_attributes (die, decl); + if (! DECL_ARTIFICIAL (decl)) + add_src_coords_attributes (die, decl); if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) @@ -7520,9 +7529,6 @@ static void push_decl_scope (scope) tree scope; { - tree containing_scope; - int i; - /* Make room in the decl_scope_table, if necessary. */ if (decl_scope_table_allocated == decl_scope_depth) { @@ -7535,32 +7541,22 @@ push_decl_scope (scope) decl_scope_table[decl_scope_depth].scope = scope; - /* Sometimes, while recursively emitting subtypes within a class type, - we end up recuring on a subtype at a higher level then the current - subtype. In such a case, we need to search the decl_scope_table to - find the parent of this subtype. */ + /* If we're starting to emit a global class while we're in the middle + of emitting a function, we need to find the proper .previous. */ if (AGGREGATE_TYPE_P (scope)) - containing_scope = TYPE_CONTEXT (scope); - else - containing_scope = NULL_TREE; - - /* The normal case. */ - if (decl_scope_depth == 0 - || containing_scope == NULL_TREE - /* Ignore namespaces for the moment. */ - || TREE_CODE (containing_scope) == NAMESPACE_DECL) - decl_scope_table[decl_scope_depth].previous = decl_scope_depth - 1; - else { - /* We need to search for the containing_scope. If we don't find it, - that's OK; we stick ourselves at global scope. */ + tree containing_scope = TYPE_CONTEXT (scope); + int i; + for (i = decl_scope_depth - 1; i >= 0; --i) if (decl_scope_table[i].scope == containing_scope) break; decl_scope_table[decl_scope_depth].previous = i; } + else + decl_scope_table[decl_scope_depth].previous = decl_scope_depth - 1; decl_scope_depth++; } @@ -8256,12 +8252,13 @@ gen_subprogram_die (decl, context_die) debugger can find it. For inlines, that is the concrete instance, so we can use the old DIE here. For non-inline methods, we want a specification DIE at toplevel, so we need a new DIE. For local - class methods, we just use the old DIE. */ + class methods, this doesn't apply; we just use the old DIE. */ if ((DECL_ABSTRACT (decl) || old_die->die_parent == comp_unit_die || context_die == NULL) - && get_AT_unsigned (old_die, DW_AT_decl_file) == file_index - && (get_AT_unsigned (old_die, DW_AT_decl_line) - == (unsigned)DECL_SOURCE_LINE (decl))) + && (DECL_ARTIFICIAL (decl) + || (get_AT_unsigned (old_die, DW_AT_decl_file) == file_index + && (get_AT_unsigned (old_die, DW_AT_decl_line) + == (unsigned)DECL_SOURCE_LINE (decl))))) { subr_die = old_die; @@ -8741,18 +8738,20 @@ gen_ptr_to_mbr_type_die (type, context_die) /* Generate the DIE for the compilation unit. */ -static void -gen_compile_unit_die (main_input_filename) - register char *main_input_filename; +static dw_die_ref +gen_compile_unit_die (filename) + register const char *filename; { + register dw_die_ref die; char producer[250]; char *wd = getpwd (); + int language; - comp_unit_die = new_die (DW_TAG_compile_unit, NULL); - add_name_attribute (comp_unit_die, main_input_filename); + die = new_die (DW_TAG_compile_unit, NULL); + add_name_attribute (die, filename); - if (wd != NULL) - add_AT_string (comp_unit_die, DW_AT_comp_dir, wd); + if (wd != NULL && filename[0] != DIR_SEPARATOR) + add_AT_string (die, DW_AT_comp_dir, wd); sprintf (producer, "%s %s", language_string, version_string); @@ -8767,30 +8766,24 @@ gen_compile_unit_die (main_input_filename) strcat (producer, " -g"); #endif - add_AT_string (comp_unit_die, DW_AT_producer, producer); + add_AT_string (die, DW_AT_producer, producer); if (strcmp (language_string, "GNU C++") == 0) - add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_C_plus_plus); - + language = DW_LANG_C_plus_plus; else if (strcmp (language_string, "GNU Ada") == 0) - add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_Ada83); - + language = DW_LANG_Ada83; else if (strcmp (language_string, "GNU F77") == 0) - add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_Fortran77); - + language = DW_LANG_Fortran77; else if (strcmp (language_string, "GNU Pascal") == 0) - add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_Pascal83); - + language = DW_LANG_Pascal83; else if (flag_traditional) - add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_C); - + language = DW_LANG_C; else - add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_C89); + language = DW_LANG_C89; -#if 0 /* unimplemented */ - if (debug_info_level >= DINFO_LEVEL_VERBOSE) - add_AT_unsigned (comp_unit_die, DW_AT_macro_info, 0); -#endif + add_AT_unsigned (die, DW_AT_language, language); + + return die; } /* Generate a DIE for a string type. */ @@ -8942,9 +8935,12 @@ gen_struct_or_union_type_die (type, context_die) { tree vtype = DECL_FCONTEXT (TYPE_VFIELD (type)); - gen_type_die (vtype, context_die); - add_AT_die_ref (type_die, DW_AT_containing_type, - lookup_type_die (vtype)); + if (vtype != type) + { + gen_type_die (vtype, context_die); + add_AT_die_ref (type_die, DW_AT_containing_type, + lookup_type_die (vtype)); + } } } else @@ -9368,11 +9364,6 @@ gen_decl_die (decl, context_die) { register tree origin; - /* Make a note of the decl node we are going to be working on. We may need - to give the user the source coordinates of where it appeared in case we - notice (later on) that something about it looks screwy. */ - dwarf_last_decl = decl; - if (TREE_CODE (decl) == ERROR_MARK) return; @@ -9926,7 +9917,7 @@ dwarf2out_init (asm_out_file, main_input_filename) will (typically) be a relative pathname and that this pathname should be taken as being relative to the directory from which the compiler was invoked when the given (base) source file was compiled. */ - gen_compile_unit_die (main_input_filename); + comp_unit_die = gen_compile_unit_die (main_input_filename); ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, ABBREV_SECTION_LABEL, 0); @@ -9941,9 +9932,11 @@ dwarf2out_init (asm_out_file, main_input_filename) ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION); ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label); - ASM_OUTPUT_SECTION (asm_out_file, TEXT_SECTION); if (DWARF2_GENERATE_TEXT_SECTION_LABEL) - ASM_OUTPUT_LABEL (asm_out_file, text_section_label); + { + ASM_OUTPUT_SECTION (asm_out_file, TEXT_SECTION); + ASM_OUTPUT_LABEL (asm_out_file, text_section_label); + } ASM_OUTPUT_SECTION (asm_out_file, DEBUG_INFO_SECTION); ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label); ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION); @@ -9958,7 +9951,6 @@ dwarf2out_finish () { limbo_die_node *node, *next_node; dw_die_ref die; - dw_attr_ref a; /* Traverse the limbo die list, and add parent/child links. The only dies without parents that should be here are concrete instances of @@ -9972,23 +9964,24 @@ dwarf2out_finish () if (die->die_parent == NULL) { - a = get_AT (die, DW_AT_abstract_origin); - if (a) - add_child_die (a->dw_attr_val.v.val_die_ref->die_parent, die); + dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); + if (origin) + add_child_die (origin->die_parent, die); else if (die == comp_unit_die) - ; + ; else abort (); } free (node); } + limbo_die_list = NULL; /* 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. */ + /* Traverse the DIE's, reverse their lists of attributes and children, + and add add sibling attributes to those DIE's that have children. */ add_sibling_attributes (comp_unit_die); /* Output a terminator label for the .text section. */ @@ -10030,6 +10023,11 @@ dwarf2out_finish () debug_line_section_label); } +#if 0 /* unimplemented */ + if (debug_info_level >= DINFO_LEVEL_VERBOSE && primary) + add_AT_unsigned (die, DW_AT_macro_info, 0); +#endif + /* Output the abbreviation table. */ fputc ('\n', asm_out_file); ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION); -- 2.7.4