This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

dwarf2out cleanup patch


This patch should reduce memory consumption of the dwarf2 code, as it
removes two pointers from the representation of a debugging entry.  It also
avoids emitting useless info in a couple of places, and improves readability.

1999-11-22  Jason Merrill  <jason@casey.cygnus.com>

	* 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.

Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.125
diff -c -p -r1.125 dwarf2out.c
*** dwarf2out.c	1999/11/17 17:29:36	1.125
--- dwarf2out.c	1999/11/23 01:05:55
*************** along with GNU CC; see the file COPYING.
*** 21,30 ****
  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?)
  	 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.
--- 21,27 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! /* 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.
*************** Boston, MA 02111-1307, USA.  */
*** 68,73 ****
--- 65,74 ----
  # 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.  */
  
*************** typedef struct die_struct
*** 2073,2082 ****
  {
    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;
--- 2074,2081 ----
*************** static int current_function_has_inlines;
*** 2362,2373 ****
  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));
--- 2361,2366 ----
*************** static void add_AT_lbl_id		PROTO((dw_die
*** 2418,2429 ****
  					       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,
  					       enum dwarf_attribute));
  static int get_AT_flag			PROTO((dw_die_ref,
  					       enum dwarf_attribute));
--- 2411,2421 ----
  					       enum dwarf_attribute, char *));
  static void add_AT_lbl_offset		PROTO((dw_die_ref,
  					       enum dwarf_attribute, char *));
  static dw_attr_ref get_AT		PROTO((dw_die_ref,
  					       enum dwarf_attribute));
! 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));
*************** static void print_die			PROTO((dw_die_re
*** 2449,2455 ****
  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_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));
--- 2441,2447 ----
  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((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));
*************** static void calc_die_sizes		PROTO((dw_di
*** 2458,2468 ****
  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 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));
--- 2450,2459 ----
  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_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 void output_die			PROTO((dw_die_ref));
  static void output_compilation_unit_header PROTO((void));
  static const char *dwarf2_name		PROTO((tree, int));
*************** static void gen_lexical_block_die	PROTO(
*** 2536,2542 ****
  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 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));
--- 2527,2533 ----
  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 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));
*************** static char debug_line_section_label[MAX
*** 2672,2682 ****
  /* 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 *));
  
  void
  dwarf2out_set_demangle_name_func (func)
!      char *(*func) PROTO((char *));
  {
    demangle_name_func = func;
  }
--- 2663,2673 ----
  /* 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 const char *(*demangle_name_func) PROTO((const char *));
  
  void
  dwarf2out_set_demangle_name_func (func)
!      const char *(*func) PROTO((const char *));
  {
    demangle_name_func = func;
  }
*************** decl_class_context (decl)
*** 3615,3621 ****
    return context;
  }
  
! /* Add an attribute/value pair to a DIE */
  
  static inline void
  add_dwarf_attr (die, attr)
--- 3606,3613 ----
    return context;
  }
  
! /* 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)
*************** add_dwarf_attr (die, attr)
*** 3624,3642 ****
  {
    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;
! 	}
      }
  }
  
  /* Add a flag value attribute to a DIE.  */
  
  static inline void
--- 3616,3633 ----
  {
    if (die != NULL && attr != NULL)
      {
!       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
*************** add_AT_flag (die, attr_kind, flag)
*** 3654,3659 ****
--- 3645,3660 ----
    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
*************** add_AT_int (die, attr_kind, int_val)
*** 3671,3676 ****
--- 3672,3687 ----
    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
*************** add_AT_unsigned (die, attr_kind, unsigne
*** 3688,3693 ****
--- 3699,3714 ----
    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
*************** add_AT_string (die, attr_kind, str)
*** 3743,3748 ****
--- 3764,3779 ----
    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
*************** add_AT_die_ref (die, attr_kind, targ_die
*** 3760,3765 ****
--- 3791,3806 ----
    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
*************** add_AT_loc (die, attr_kind, loc)
*** 3794,3799 ****
--- 3835,3850 ----
    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
*************** add_AT_addr (die, attr_kind, addr)
*** 3811,3816 ****
--- 3862,3877 ----
    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
*************** add_AT_lbl_offset (die, attr_kind, label
*** 3841,3877 ****
    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;
    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;
  {
!   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;
! 	    }
! 	}
!     }
  
!   return is_subr && is_extern;
  }
  
  /* Get the attribute of type attr_kind.  */
--- 3902,3921 ----
    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 = xstrdup (label);
    add_dwarf_attr (die, attr);
    
  }
  
! static inline const char *
! AT_lbl (a)
!      register dw_attr_ref a;
  {
!   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 NULL;
  }
  
  /* Get the attribute of type attr_kind.  */
*************** get_AT (die, attr_kind)
*** 3893,3899 ****
  
  	  if (a->dw_attr == DW_AT_specification
  	      || a->dw_attr == DW_AT_abstract_origin)
! 	    spec = a->dw_attr_val.v.val_die_ref;
  	}
  
        if (spec)
--- 3937,3943 ----
  
  	  if (a->dw_attr == DW_AT_specification
  	      || a->dw_attr == DW_AT_abstract_origin)
! 	    spec = AT_ref (a);
  	}
  
        if (spec)
*************** get_AT (die, attr_kind)
*** 3908,3923 ****
     either not prsent, or if it cannot be represented as an
     assembler label identifier.  */
  
! static inline 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 the "high pc" attribute value, typically associated with
--- 3952,3963 ----
     either not prsent, or if it cannot be represented as an
     assembler label identifier.  */
  
! 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);
!   return AT_lbl (a);
  }
  
  /* Return the "high pc" attribute value, typically associated with
*************** get_AT_low_pc (die)
*** 3925,3956 ****
     either not prsent, or if it cannot be represented as an
     assembler label identifier.  */
  
! static inline 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 the value of the string attribute designated by ATTR_KIND, or
     NULL if it is not present.  */
  
! static inline 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 the value of the flag attribute designated by ATTR_KIND, or -1
--- 3965,3988 ----
     either not prsent, or if it cannot be represented as an
     assembler label identifier.  */
  
! 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);
!   return AT_lbl (a);
  }
  
  /* Return the value of the string attribute designated by ATTR_KIND, or
     NULL if it is not present.  */
  
! 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);
!   return AT_string (a);
  }
  
  /* Return the value of the flag attribute designated by ATTR_KIND, or -1
*************** get_AT_flag (die, attr_kind)
*** 3962,3972 ****
       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 the value of the unsigned attribute designated by ATTR_KIND, or 0
--- 3994,4000 ----
       register enum dwarf_attribute attr_kind;
  {
    register dw_attr_ref a = get_AT (die, attr_kind);
!   return AT_flag (a);
  }
  
  /* Return the value of the unsigned attribute designated by ATTR_KIND, or 0
*************** get_AT_unsigned (die, attr_kind)
*** 3978,3988 ****
       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_unsigned_const)
!     return a->dw_attr_val.v.val_unsigned;
  
!   return 0;
  }
  
  static inline int
--- 4006,4021 ----
       register enum dwarf_attribute attr_kind;
  {
    register dw_attr_ref a = get_AT (die, attr_kind);
!   return AT_unsigned (a);
! }
  
! 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
*************** remove_AT (die, attr_kind)
*** 4009,4043 ****
       register dw_die_ref die;
       register enum dwarf_attribute attr_kind;
  {
!   register dw_attr_ref a;
    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;
! 	}
  
!       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)
  	    {
! 	      removed = a->dw_attr_next;
! 	      if (die->die_attr_last == a->dw_attr_next)
! 		die->die_attr_last = a;
  
! 	      a->dw_attr_next = a->dw_attr_next->dw_attr_next;
  	      break;
  	    }
  
!       if (removed != 0)
! 	free (removed);
      }
  }
  
--- 4042,4077 ----
       register dw_die_ref die;
       register enum dwarf_attribute attr_kind;
  {
!   register dw_attr_ref *p;
    register dw_attr_ref removed = NULL;
  
    if (die != NULL)
      {
!       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;
! 	  }
  
!       if (removed != 0)
! 	{
! 	  switch (AT_class (removed))
  	    {
! 	    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;
  
! 	    default:
  	      break;
  	    }
  
! 	  free (removed);
! 	}
      }
  }
  
*************** remove_children (die)
*** 4050,4056 ****
    register dw_die_ref child_die = die->die_child;
  
    die->die_child = NULL;
-   die->die_child_last = NULL;
  
    while (child_die != NULL)
      {
--- 4084,4089 ----
*************** remove_children (die)
*** 4071,4077 ****
      }
  }
  
! /* Add a child DIE below its parent.  */
  
  static inline void
  add_child_die (die, child_die)
--- 4104,4111 ----
      }
  }
  
! /* 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)
*************** add_child_die (die, child_die)
*** 4083,4100 ****
        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;
! 	}
      }
  }
  
--- 4117,4124 ----
        if (die == child_die)
  	abort ();
        child_die->die_parent = die;
!       child_die->die_sib = die->die_child;
!       die->die_child = child_die;
      }
  }
  
*************** new_die (tag_value, parent_die)
*** 4113,4121 ****
    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);
--- 4137,4143 ----
*************** print_die (die, outfile)
*** 4271,4277 ****
        print_spaces (outfile);
        fprintf (outfile, "  %s: ", dwarf_attr_name (a->dw_attr));
  
!       switch (a->dw_attr_val.val_class)
  	{
  	case dw_val_class_addr:
  	  fprintf (outfile, "address");
--- 4293,4299 ----
        print_spaces (outfile);
        fprintf (outfile, "  %s: ", dwarf_attr_name (a->dw_attr));
  
!       switch (AT_class (a))
  	{
  	case dw_val_class_addr:
  	  fprintf (outfile, "address");
*************** print_die (die, outfile)
*** 4280,4289 ****
  	  fprintf (outfile, "location descriptor");
  	  break;
  	case dw_val_class_const:
! 	  fprintf (outfile, "%ld", a->dw_attr_val.v.val_int);
  	  break;
  	case dw_val_class_unsigned_const:
! 	  fprintf (outfile, "%lu", a->dw_attr_val.v.val_unsigned);
  	  break;
  	case dw_val_class_long_long:
  	  fprintf (outfile, "constant (%lu,%lu)",
--- 4302,4311 ----
  	  fprintf (outfile, "location descriptor");
  	  break;
  	case dw_val_class_const:
! 	  fprintf (outfile, "%ld", AT_int (a));
  	  break;
  	case dw_val_class_unsigned_const:
! 	  fprintf (outfile, "%lu", AT_unsigned (a));
  	  break;
  	case dw_val_class_long_long:
  	  fprintf (outfile, "constant (%lu,%lu)",
*************** print_die (die, outfile)
*** 4294,4315 ****
  	  fprintf (outfile, "floating-point constant");
  	  break;
  	case dw_val_class_flag:
! 	  fprintf (outfile, "%u", a->dw_attr_val.v.val_flag);
  	  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);
  	  else
  	    fprintf (outfile, "die -> <null>");
  	  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);
  	  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);
  	  else
  	    fprintf (outfile, "<null>");
  	  break;
--- 4316,4336 ----
  	  fprintf (outfile, "floating-point constant");
  	  break;
  	case dw_val_class_flag:
! 	  fprintf (outfile, "%u", AT_flag (a));
  	  break;
  	case dw_val_class_die_ref:
! 	  if (AT_ref (a) != NULL)
! 	    fprintf (outfile, "die -> %lu", AT_ref (a)->die_offset);
  	  else
  	    fprintf (outfile, "die -> <null>");
  	  break;
  	case dw_val_class_lbl_id:
  	case dw_val_class_lbl_offset:
! 	  fprintf (outfile, "label: %s", AT_lbl (a));
  	  break;
  	case dw_val_class_str:
! 	  if (AT_string (a) != NULL)
! 	    fprintf (outfile, "\"%s\"", AT_string (a));
  	  else
  	    fprintf (outfile, "<null>");
  	  break;
*************** debug_dwarf ()
*** 4374,4405 ****
      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.  */
  
  static void
! add_sibling_attributes(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;
  
!       /* 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;
  
!       die->die_attr = attr;
      }
  
    for (c = die->die_child; c != NULL; c = c->die_sib)
      add_sibling_attributes (c);
  }
--- 4395,4445 ----
      print_dwarf_line_table (stderr);
  }
  
! /* 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
! reverse_die_lists (die)
       register dw_die_ref die;
  {
!   register dw_die_ref c, cp, cn;
!   register dw_attr_ref a, ap, an;
  
!   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;
  
!   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);
  }
*************** build_abbrev_table (die)
*** 4432,4439 ****
  	      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)))
  		    break;
  
  		  a_attr = a_attr->dw_attr_next;
--- 4472,4478 ----
  	      while (a_attr != NULL && d_attr != NULL)
  		{
  		  if ((a_attr->dw_attr != d_attr->dw_attr)
! 		      || (value_format (a_attr) != value_format (d_attr)))
  		    break;
  
  		  a_attr = a_attr->dw_attr_next;
*************** build_abbrev_table (die)
*** 4478,4484 ****
  
  static unsigned long
  size_of_string (str)
!      register char *str;
  {
    return strlen (str) + 1;
  }
--- 4517,4523 ----
  
  static unsigned long
  size_of_string (str)
!      register const char *str;
  {
    return strlen (str) + 1;
  }
*************** size_of_die (die)
*** 4632,4646 ****
    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)
  	{
  	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);
  
  	    /* Block length.  */
  	    size += constant_size (lsize);
--- 4671,4684 ----
    size += size_of_uleb128 (die->die_abbrev);
    for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
      {
!       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 (AT_loc (a));
  
  	    /* Block length.  */
  	    size += constant_size (lsize);
*************** size_of_die (die)
*** 4651,4657 ****
  	  size += 4;
  	  break;
  	case dw_val_class_unsigned_const:
! 	  size += constant_size (a->dw_attr_val.v.val_unsigned);
  	  break;
  	case dw_val_class_long_long:
  	  size += 1 + 8; /* block */
--- 4689,4695 ----
  	  size += 4;
  	  break;
  	case dw_val_class_unsigned_const:
! 	  size += constant_size (AT_unsigned (a));
  	  break;
  	case dw_val_class_long_long:
  	  size += 1 + 8; /* block */
*************** size_of_die (die)
*** 4675,4681 ****
  	  size += DWARF_OFFSET_SIZE;
  	  break;
  	case dw_val_class_str:
! 	  size += size_of_string (a->dw_attr_val.v.val_str);
  	  break;
  	default:
  	  abort ();
--- 4713,4719 ----
  	  size += DWARF_OFFSET_SIZE;
  	  break;
  	case dw_val_class_str:
! 	  size += size_of_string (AT_string (a));
  	  break;
  	default:
  	  abort ();
*************** size_of_aranges ()
*** 4787,4801 ****
  /* Select the encoding of an attribute value.  */
  
  static enum dwarf_form
! value_format (v)
!      dw_val_ref v;
  {
!   switch (v->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)))
  	{
  	case 1:
  	  return DW_FORM_block1;
--- 4825,4839 ----
  /* Select the encoding of an attribute value.  */
  
  static enum dwarf_form
! value_format (a)
!      dw_attr_ref a;
  {
!   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 (AT_loc (a))))
  	{
  	case 1:
  	  return DW_FORM_block1;
*************** value_format (v)
*** 4807,4813 ****
      case dw_val_class_const:
        return DW_FORM_data4;
      case dw_val_class_unsigned_const:
!       switch (constant_size (v->v.val_unsigned))
  	{
  	case 1:
  	  return DW_FORM_data1;
--- 4845,4851 ----
      case dw_val_class_const:
        return DW_FORM_data4;
      case dw_val_class_unsigned_const:
!       switch (constant_size (AT_unsigned (a)))
  	{
  	case 1:
  	  return DW_FORM_data1;
*************** value_format (v)
*** 4844,4853 ****
  /* Output the encoding of an attribute value.  */
  
  static void
! output_value_format (v)
!      dw_val_ref v;
  {
!   enum dwarf_form form = value_format (v);
  
    output_uleb128 (form);
    if (flag_debug_asm)
--- 4882,4891 ----
  /* Output the encoding of an attribute value.  */
  
  static void
! output_value_format (a)
!      dw_attr_ref a;
  {
!   enum dwarf_form form = value_format (a);
  
    output_uleb128 (form);
    if (flag_debug_asm)
*************** output_abbrev_section ()
*** 4900,4906 ****
  		     dwarf_attr_name (a_attr->dw_attr));
  
  	  fputc ('\n', asm_out_file);
! 	  output_value_format (&a_attr->dw_attr_val);
  	}
  
        fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP);
--- 4938,4944 ----
  		     dwarf_attr_name (a_attr->dw_attr));
  
  	  fputc ('\n', asm_out_file);
! 	  output_value_format (a_attr);
  	}
  
        fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP);
*************** output_loc_operands (loc)
*** 5029,5050 ****
      }
  }
  
- /* 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.  */
  
--- 5067,5072 ----
*************** output_die (die)
*** 5054,5060 ****
  {
    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;
  
--- 5076,5081 ----
*************** output_die (die)
*** 5067,5081 ****
  
    for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
      {
!       switch (a->dw_attr_val.val_class)
  	{
  	case dw_val_class_addr:
! 	  ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file,
! 				       a->dw_attr_val.v.val_addr);
  	  break;
  
  	case dw_val_class_loc:
! 	  size = size_of_locs (a->dw_attr_val.v.val_loc);
  
  	  /* Output the block length for this list of location operations.  */
  	  switch (constant_size (size))
--- 5088,5101 ----
  
    for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
      {
!       switch (AT_class (a))
  	{
  	case dw_val_class_addr:
! 	  ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, AT_addr (a));
  	  break;
  
  	case dw_val_class_loc:
! 	  size = size_of_locs (AT_loc (a));
  
  	  /* Output the block length for this list of location operations.  */
  	  switch (constant_size (size))
*************** output_die (die)
*** 5095,5102 ****
  		     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)
  	    {
  	      /* Output the opcode.  */
  	      ASM_OUTPUT_DWARF_DATA1 (asm_out_file, loc->dw_loc_opc);
--- 5115,5121 ----
  		     ASM_COMMENT_START, dwarf_attr_name (a->dw_attr));
  
  	  fputc ('\n', asm_out_file);
! 	  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);
*************** output_die (die)
*** 5112,5134 ****
  	  break;
  
  	case dw_val_class_const:
! 	  ASM_OUTPUT_DWARF_DATA4 (asm_out_file, a->dw_attr_val.v.val_int);
  	  break;
  
  	case dw_val_class_unsigned_const:
! 	  switch (constant_size (a->dw_attr_val.v.val_unsigned))
  	    {
  	    case 1:
! 	      ASM_OUTPUT_DWARF_DATA1 (asm_out_file,
! 				      a->dw_attr_val.v.val_unsigned);
  	      break;
  	    case 2:
! 	      ASM_OUTPUT_DWARF_DATA2 (asm_out_file,
! 				      a->dw_attr_val.v.val_unsigned);
  	      break;
  	    case 4:
! 	      ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
! 				      a->dw_attr_val.v.val_unsigned);
  	      break;
  	    case 8:
  	      ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
--- 5131,5150 ----
  	  break;
  
  	case dw_val_class_const:
! 	  ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_int (a));
  	  break;
  
  	case dw_val_class_unsigned_const:
! 	  switch (constant_size (AT_unsigned (a)))
  	    {
  	    case 1:
! 	      ASM_OUTPUT_DWARF_DATA1 (asm_out_file, AT_unsigned (a));
  	      break;
  	    case 2:
! 	      ASM_OUTPUT_DWARF_DATA2 (asm_out_file, AT_unsigned (a));
  	      break;
  	    case 4:
! 	      ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_unsigned (a));
  	      break;
  	    case 8:
  	      ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
*************** output_die (die)
*** 5182,5199 ****
  	  }
  
  	case dw_val_class_flag:
! 	  ASM_OUTPUT_DWARF_DATA1 (asm_out_file, a->dw_attr_val.v.val_flag);
  	  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);
  	  break;
  
  	case dw_val_class_fde_ref:
--- 5198,5208 ----
  	  }
  
  	case dw_val_class_flag:
! 	  ASM_OUTPUT_DWARF_DATA1 (asm_out_file, AT_flag (a));
  	  break;
  
  	case dw_val_class_die_ref:
! 	  ASM_OUTPUT_DWARF_DATA (asm_out_file, AT_ref (a)->die_offset);
  	  break;
  
  	case dw_val_class_fde_ref:
*************** output_die (die)
*** 5207,5235 ****
  	  break;
  
  	case dw_val_class_lbl_id:
! 	  ASM_OUTPUT_DWARF_ADDR (asm_out_file, a->dw_attr_val.v.val_lbl_id);
  	  break;
  
  	case dw_val_class_lbl_offset:
! 	  ASM_OUTPUT_DWARF_OFFSET (asm_out_file, a->dw_attr_val.v.val_lbl_id);
  	  break;
  
  	case dw_val_class_str:
  	  if (flag_debug_asm)
! 	    ASM_OUTPUT_DWARF_STRING (asm_out_file, a->dw_attr_val.v.val_str);
  	  else
! 	    ASM_OUTPUT_ASCII (asm_out_file,
! 			      a->dw_attr_val.v.val_str,
! 			      (int) strlen (a->dw_attr_val.v.val_str) + 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 (flag_debug_asm)
  	    fprintf (asm_out_file, "\t%s %s",
--- 5216,5243 ----
  	  break;
  
  	case dw_val_class_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, AT_lbl (a));
  	  break;
  
  	case dw_val_class_str:
  	  if (flag_debug_asm)
! 	    ASM_OUTPUT_DWARF_STRING (asm_out_file, AT_string (a));
  	  else
! 	    ASM_OUTPUT_ASCII (asm_out_file, AT_string (a),
! 			      (int) strlen (AT_string (a)) + 1);
  	  break;
  
  	default:
  	  abort ();
  	}
  
!       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",
*************** output_aranges ()
*** 5482,5491 ****
  
  	  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)
  	    abort ();
  
! 	  loc = a->dw_attr_val.v.val_loc;
  	  if (loc->dw_loc_opc != DW_OP_addr)
  	    abort ();
  
--- 5490,5499 ----
  
  	  dw_attr_ref a = get_AT (die, DW_AT_location);
  	  dw_loc_descr_ref loc;
! 	  if (! a || AT_class (a) != dw_val_class_loc)
  	    abort ();
  
! 	  loc = AT_loc (a);
  	  if (loc->dw_loc_opc != DW_OP_addr)
  	    abort ();
  
*************** add_name_and_src_coords_attributes (die,
*** 7505,7511 ****
    if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL)
      {
        add_name_attribute (die, dwarf2_name (decl, 0));
!       add_src_coords_attributes (die, decl);
  
        if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
  	  && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
--- 7513,7520 ----
    if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL)
      {
        add_name_attribute (die, dwarf2_name (decl, 0));
!       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))
*************** static void
*** 7520,7528 ****
  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)
      {
--- 7529,7534 ----
*************** push_decl_scope (scope)
*** 7535,7566 ****
  
    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 (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.  */
        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;
      }
  
    decl_scope_depth++;
  }
--- 7541,7562 ----
  
    decl_scope_table[decl_scope_depth].scope = scope;
  
!   /* 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))
      {
!       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++;
  }
*************** gen_subprogram_die (decl, context_die)
*** 8256,8267 ****
  	 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.  */
        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)))
  	{
  	  subr_die = old_die;
  
--- 8252,8264 ----
  	 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, this doesn't apply; we just use the old DIE.  */
        if ((DECL_ABSTRACT (decl) || old_die->die_parent == comp_unit_die
  	   || context_die == NULL)
! 	  && (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;
  
*************** gen_ptr_to_mbr_type_die (type, context_d
*** 8741,8758 ****
  
  /* Generate the DIE for the compilation unit.  */
  
! static void
! gen_compile_unit_die (main_input_filename)
!      register char *main_input_filename;
  {
    char producer[250];
    char *wd = getpwd ();
  
!   comp_unit_die = new_die (DW_TAG_compile_unit, NULL);
!   add_name_attribute (comp_unit_die, main_input_filename);
  
!   if (wd != NULL)
!     add_AT_string (comp_unit_die, DW_AT_comp_dir, wd);
  
    sprintf (producer, "%s %s", language_string, version_string);
  
--- 8738,8757 ----
  
  /* Generate the DIE for the compilation unit.  */
  
! 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;
  
!   die = new_die (DW_TAG_compile_unit, NULL);
!   add_name_attribute (die, filename);
  
!   if (wd != NULL && filename[0] != DIR_SEPARATOR)
!     add_AT_string (die, DW_AT_comp_dir, wd);
  
    sprintf (producer, "%s %s", language_string, version_string);
  
*************** gen_compile_unit_die (main_input_filenam
*** 8767,8796 ****
      strcat (producer, " -g");
  #endif
  
!   add_AT_string (comp_unit_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);
! 
    else if (strcmp (language_string, "GNU Ada") == 0)
!     add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_Ada83);
! 
    else if (strcmp (language_string, "GNU F77") == 0)
!     add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_Fortran77);
! 
    else if (strcmp (language_string, "GNU Pascal") == 0)
!     add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_Pascal83);
! 
    else if (flag_traditional)
!     add_AT_unsigned (comp_unit_die, DW_AT_language, DW_LANG_C);
! 
    else
!     add_AT_unsigned (comp_unit_die, DW_AT_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
  }
  
  /* Generate a DIE for a string type.  */
--- 8766,8789 ----
      strcat (producer, " -g");
  #endif
  
!   add_AT_string (die, DW_AT_producer, producer);
  
    if (strcmp (language_string, "GNU C++") == 0)
!     language = DW_LANG_C_plus_plus;
    else if (strcmp (language_string, "GNU Ada") == 0)
!     language = DW_LANG_Ada83;
    else if (strcmp (language_string, "GNU F77") == 0)
!     language = DW_LANG_Fortran77;
    else if (strcmp (language_string, "GNU Pascal") == 0)
!     language = DW_LANG_Pascal83;
    else if (flag_traditional)
!     language = DW_LANG_C;
    else
!     language = DW_LANG_C89;
  
!   add_AT_unsigned (die, DW_AT_language, language);
! 
!   return die;
  }
  
  /* Generate a DIE for a string type.  */
*************** gen_struct_or_union_type_die (type, cont
*** 8942,8950 ****
  	{
  	  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));
  	}
      }
    else
--- 8935,8946 ----
  	{
  	  tree vtype = DECL_FCONTEXT (TYPE_VFIELD (type));
  
! 	  if (vtype != type)
! 	    {
! 	      gen_type_die (vtype, context_die);
! 	      add_AT_die_ref (type_die, DW_AT_containing_type,
! 			      lookup_type_die (vtype));
! 	    }
  	}
      }
    else
*************** gen_decl_die (decl, context_die)
*** 9368,9378 ****
  {
    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;
  
--- 9364,9369 ----
*************** dwarf2out_init (asm_out_file, main_input
*** 9926,9932 ****
       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);
  
    ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
    ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, ABBREV_SECTION_LABEL, 0);
--- 9917,9923 ----
       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.  */
!   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);
*************** dwarf2out_init (asm_out_file, main_input
*** 9941,9949 ****
  
    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, DEBUG_INFO_SECTION);
    ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
    ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
--- 9932,9942 ----
  
    ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
    ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
    if (DWARF2_GENERATE_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);
*************** dwarf2out_finish ()
*** 9958,9964 ****
  {
    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
--- 9951,9956 ----
*************** dwarf2out_finish ()
*** 9972,9994 ****
  
        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);
  	  else if (die == comp_unit_die)
! 	      ;
  	  else
  	    abort ();
  	}
        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);
  
    /* Output a terminator label for the .text section.  */
--- 9964,9987 ----
  
        if (die->die_parent == NULL)
  	{
! 	  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'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.  */
*************** dwarf2out_finish ()
*** 10029,10034 ****
--- 10022,10032 ----
        add_AT_lbl_offset (comp_unit_die, DW_AT_stmt_list,
  			 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]