This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] DWARF2 namespace support
- To: gcc-patches at gcc dot gnu dot org, jason at redhat dot com
- Subject: [PATCH] DWARF2 namespace support
- From: Daniel Berlin <dan at cgsoftware dot com>
- Date: Tue, 06 Nov 2001 06:47:07 -0500
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