This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: adding namespace support to GDB
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: Petr Sorfa <petrs at caldera dot com>
- Cc: David Carlton <carlton at math dot stanford dot edu>,gdb <gdb at sources dot redhat dot com>, <jlw at caldera dot com>
- Date: Fri, 23 Aug 2002 18:35:50 -0400 (EDT)
- Subject: Re: adding namespace support to GDB
- Reply-to: dberlin at dberlin dot org
On Fri, 23 Aug 2002, Petr Sorfa wrote:
> Hi Daniel,
>
> Well, let me or John Wolfe submit a patch with the imported declaration
> support next week. It will at least be some kind of comparison.
My gcc patch already includes this.
I've rediffed against current gcc sources, and pasted it below.
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.379.2.3
diff -c -3 -p -w -B -b -r1.379.2.3 dwarf2out.c
*** dwarf2out.c 19 Aug 2002 01:30:33 -0000 1.379.2.3
--- dwarf2out.c 23 Aug 2002 22:33:11 -0000
*************** static void gen_tagged_type_instantiatio
*** 3648,3654 ****
--- 3648,3656 ----
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 retry_incomplete_types PARAMS ((void));
*************** dwarf_tag_name (tag)
*** 3905,3910 ****
--- 3907,3914 ----
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)
*** 9540,9548 ****
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
--- 9544,9563 ----
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)
*** 11374,11379 ****
--- 11389,11453 ----
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, decl);
+ 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, decl);
+ 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. */
*************** gen_decl_die (decl, context_die)
*** 11424,11429 ****
--- 11498,11505 ----
/* 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)
*** 11447,11453 ****
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 (e.g. one which
--- 11523,11529 ----
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 (e.g. one which
*************** gen_decl_die (decl, context_die)
*** 11477,11482 ****
--- 11553,11559 ----
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)
*** 11504,11509 ****
--- 11581,11587 ----
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)
*** 11515,11521 ****
break;
case NAMESPACE_DECL:
! /* Ignore for now. */
break;
default:
--- 11593,11600 ----
break;
case NAMESPACE_DECL:
! context_die = force_out_decl (decl, context_die);
! gen_namespace_die (decl, context_die);
break;
default:
*************** dwarf2out_decl (decl)
*** 11668,11673 ****
--- 11747,11759 ----
/* If we are in terse mode, don't generate any DIEs for types. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
+ case NAMESPACE_DECL:
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+ if (lookup_decl_die (decl) != NULL)
+ return;
+ break;
+
return;
/* If we're a function-scope tag, initially use a parent of NULL;