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]

[PATCH] DWARF2 namespace support


Jason approved this eons ago (I never got around to committing it), with the condition that I move the
forcing out of namespaces/etc into a seperate function, named
force_out_decl.

I just wanted to make sure this is what he had in mind.

Note that this is going to break C++ debugging on debuggers without even trivial
support for the draft dwarf 3.0 (since the things in a namespace are
children of the namespace die, and debuggers that just ignore DE's
they don't comprehend don't look at the children of ignored DIE's).
Since this isn't the only nice thing in dwarf 3.0 that it would be
good to start implementing or are implemented (The location lists
support the 3.0 extension to allow a base address specifier, so if a
variable is in two sections, depending on the pc, we can properly
describe the location, for instance), it might make sense to add a
-gdwarf-3 flag, and only output namespaces, etc, when it is given,
until more debuggers support the dwarf 3 draft features.

Thoughts?

Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.324
diff -c -3 -p -w -B -b -r1.324 dwarf2out.c
*** dwarf2out.c	2001/10/29 12:24:17	1.324
--- dwarf2out.c	2001/11/06 15:33:44
*************** static void gen_tagged_type_instantiatio
*** 3577,3583 ****
--- 3577,3585 ----
  static void gen_block_die		PARAMS ((tree, dw_die_ref, int));
  static void decls_for_scope		PARAMS ((tree, dw_die_ref, int));
  static int is_redundant_typedef		PARAMS ((tree));
+ static void gen_namespace_die           PARAMS ((tree, dw_die_ref));
  static void gen_decl_die		PARAMS ((tree, dw_die_ref));
+ static dw_die_ref force_out_decl	PARAMS ((tree, dw_die_ref));
  static unsigned lookup_filename		PARAMS ((const char *));
  static void init_file_table		PARAMS ((void));
  static void add_incomplete_type		PARAMS ((tree));
*************** dwarf_tag_name (tag)
*** 3847,3852 ****
--- 3849,3856 ----
        return "DW_TAG_namelist";
      case DW_TAG_namelist_item:
        return "DW_TAG_namelist_item";
+     case DW_TAG_namespace:
+       return "DW_TAG_namespace";
      case DW_TAG_packed_type:
        return "DW_TAG_packed_type";
      case DW_TAG_subprogram:
*************** scope_die_for (t, context_die)
*** 9219,9227 ****
  
    containing_scope = TYPE_CONTEXT (t);
  
!   /* Ignore namespaces for the moment.  */
    if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
!     containing_scope = NULL_TREE;
  
    /* Ignore function type "scopes" from the C frontend.  They mean that
       a tagged type is local to a parmlist of a function declarator, but
--- 9223,9242 ----
  
    containing_scope = TYPE_CONTEXT (t);
  
!   /* Handle namespaces properly */
    if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
!     {
!       dw_die_ref newcontext = lookup_decl_die (containing_scope);
! 
!       if (!newcontext)
! 	{
! 	  gen_decl_die (containing_scope, context_die);
! 	  newcontext = lookup_decl_die (containing_scope);
! 	  if (!newcontext)
! 	    abort();
! 	}
!       context_die = newcontext;
!     }
  
    /* Ignore function type "scopes" from the C frontend.  They mean that
       a tagged type is local to a parmlist of a function declarator, but
*************** is_redundant_typedef (decl)
*** 11038,11044 ****
--- 11053,11118 ----
  
    return 0;
  }
+ static dw_die_ref
+ force_out_decl (decl, context_die)
+ 	tree decl;
+ 	dw_die_ref context_die;
+ {
+   /* Force out the namespace. */
+   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
+     {
+       dw_die_ref newcontext;
+       newcontext = lookup_decl_die (DECL_CONTEXT (decl));
+       if (!newcontext)
+ 	{
+ 	  gen_decl_die (DECL_CONTEXT (decl), context_die);
+ 	  newcontext = lookup_decl_die (DECL_CONTEXT (decl));
+ 	  if (!newcontext)
+ 	    abort();
+ 	}
+       context_die = newcontext;
+     }
+   return context_die;
+ }
  
+ /* Generate a DIE for a namespace or namespace alias */
+ static void
+ gen_namespace_die (decl, context_die)
+      register tree decl;
+      register dw_die_ref context_die;
+ {
+   /* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace
+      they are an alias of.*/
+   if (DECL_ABSTRACT_ORIGIN (decl) == NULL)
+     {
+       /* Output a real namespace */
+       dw_die_ref namespace_die = new_die (DW_TAG_namespace, context_die);
+       add_name_and_src_coords_attributes (namespace_die, decl);
+       equate_decl_number_to_die (decl, namespace_die);
+     }
+   else
+     {
+       /* Output a namespace alias */
+       dw_die_ref namespace_die;
+       
+       /* Force out the namespace we are an alias of, if necessary */
+       dw_die_ref origin_die = lookup_decl_die  (DECL_ABSTRACT_ORIGIN (decl));
+       if (!origin_die)
+ 	{
+ 	  /* Attempt to force out origin. */
+ 	  dwarf2out_decl (DECL_ABSTRACT_ORIGIN (decl));
+ 	  origin_die = lookup_decl_die (DECL_ABSTRACT_ORIGIN (decl));
+ 	  if (!origin_die)
+ 	    abort();
+ 	}
+       /* Now create the namespace alias DIE. */
+       namespace_die = new_die (DW_TAG_imported_declaration, context_die);
+       add_name_and_src_coords_attributes (namespace_die, decl);
+       add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
+       equate_decl_number_to_die (decl, namespace_die);
+     }
+ }
+ 
  /* Generate Dwarf debug information for a decl described by DECL.  */
  
  static void
*************** gen_decl_die (decl, context_die)
*** 11087,11092 ****
--- 11161,11168 ----
        /* Otherwise we're emitting the primary DIE for this decl.  */
        else if (debug_info_level > DINFO_LEVEL_TERSE)
  	{
+ 	  context_die = force_out_decl (decl, context_die);
+ 
  	  /* Before we describe the FUNCTION_DECL itself, make sure that we
  	     have described its return type.  */
  	  gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
*************** gen_decl_die (decl, context_die)
*** 11110,11116 ****
           actual typedefs.  */
        if (debug_info_level <= DINFO_LEVEL_TERSE)
  	break;
! 
        /* In the special case of a TYPE_DECL node representing the
           declaration of some type tag, if the given TYPE_DECL is marked as
           having been instantiated from some other (original) TYPE_DECL node
--- 11187,11193 ----
           actual typedefs.  */
        if (debug_info_level <= DINFO_LEVEL_TERSE)
  	break;
!       context_die = force_out_decl (decl, context_die);
        /* In the special case of a TYPE_DECL node representing the
           declaration of some type tag, if the given TYPE_DECL is marked as
           having been instantiated from some other (original) TYPE_DECL node
*************** gen_decl_die (decl, context_die)
*** 11141,11146 ****
--- 11218,11224 ----
           variable declarations or definitions.  */
        if (debug_info_level <= DINFO_LEVEL_TERSE)
  	break;
+       context_die = force_out_decl (decl, context_die);
  
        /* Output any DIEs that are needed to specify the type of this data
           object.  */
*************** gen_decl_die (decl, context_die)
*** 11168,11173 ****
--- 11246,11252 ----
        if (DECL_NAME (decl) != NULL_TREE
  	  || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE)
  	{
+ 	  context_die = force_out_decl (decl, context_die);
  	  gen_type_die (member_declared_type (decl), context_die);
  	  gen_field_die (decl, context_die);
  	}
*************** gen_decl_die (decl, context_die)
*** 11179,11185 ****
        break;
  
      case NAMESPACE_DECL:
!       /* Ignore for now.  */
        break;
  
      default:
--- 11258,11265 ----
        break;
  
      case NAMESPACE_DECL:
!       context_die = force_out_decl (decl, context_die);
!       gen_namespace_die (decl, context_die);
        break;
  
      default:
*************** dwarf2out_decl (decl)
*** 11334,11339 ****
--- 11414,11426 ----
  
        break;
        
+     case NAMESPACE_DECL:
+       if (debug_info_level <= DINFO_LEVEL_TERSE)
+ 	return;
+       if (lookup_decl_die (decl) != NULL)
+         return;
+       break;
+       
      default:
        return;
      }


-- 
"Winny would spend all of his time practicing limbo.  He got
pretty good.  He could go under a rug.
"-Steven Wright


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