[PATCH]: Updated patch to output dwarf2 namespace debug info
Daniel Berlin
dberlin@dberlin.org
Mon Dec 1 03:40:00 GMT 2003
This one works and passes regtests.
Okay to commit?
2003-11-31 Daniel Berlin <dberlin@dberlin.org>
* dwarf2out.c (force_out_decl): New function.
(gen_namespace_die): New function.
(scope_die_for): Handle namespaces.
(class_scope_p): Ditto.
(gen_decl_die): Ditto.
(dwarf2out_decl): Ditto.
* tree.h: Move anonymous_namespace_name declaration to here.
* tree.c: And the variable to here.
* cp/decl.c: From here.
* cp/cp-tree.h: And here.
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.465
diff -u -3 -p -r1.465 dwarf2out.c
--- dwarf2out.c 21 Nov 2003 21:18:45 -0000 1.465
+++ dwarf2out.c 1 Dec 2003 03:29:21 -0000
@@ -3740,7 +3740,7 @@ static void push_decl_scope (tree);
static void pop_decl_scope (void);
static dw_die_ref scope_die_for (tree, dw_die_ref);
static inline int local_scope_p (dw_die_ref);
-static inline int class_scope_p (dw_die_ref);
+static inline int class_or_namespace_scope_p (dw_die_ref);
static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
static const char *type_tag (tree);
static tree member_declared_type (tree);
@@ -3778,7 +3778,10 @@ static void gen_tagged_type_instantiatio
static void gen_block_die (tree, dw_die_ref, int);
static void decls_for_scope (tree, dw_die_ref, int);
static int is_redundant_typedef (tree);
+static void gen_namespace_die (tree, dw_die_ref);
+static dw_die_ref scope_die_for_namespace (dw_die_ref);
static void gen_decl_die (tree, dw_die_ref);
+static dw_die_ref setup_namespace_context (tree, dw_die_ref);
static unsigned lookup_filename (const char *);
static void init_file_table (void);
static void retry_incomplete_types (void);
@@ -4034,6 +4037,8 @@ dwarf_tag_name (unsigned int tag)
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:
@@ -10020,9 +10025,20 @@ scope_die_for (tree t, dw_die_ref contex
containing_scope = TYPE_CONTEXT (t);
- /* Ignore namespaces for the moment. */
+ /* Handle namespaces properly */
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
- containing_scope = NULL_TREE;
+ {
+ 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
@@ -10075,11 +10091,12 @@ local_scope_p (dw_die_ref context_die)
/* Returns nonzero if CONTEXT_DIE is a class. */
static inline int
-class_scope_p (dw_die_ref context_die)
+class_or_namespace_scope_p (dw_die_ref context_die)
{
return (context_die
&& (context_die->die_tag == DW_TAG_structure_type
- || context_die->die_tag == DW_TAG_union_type));
+ || context_die->die_tag == DW_TAG_union_type
+ || context_die->die_tag == DW_TAG_namespace));
}
/* Many forms of DIEs require a "type description" attribute. This
@@ -10599,7 +10616,7 @@ gen_subprogram_die (tree decl, dw_die_re
tree outer_scope;
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (current_function_decl != decl
- || class_scope_p (context_die));
+ || class_or_namespace_scope_p (context_die));
/* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we
started to generate the abstract instance of an inline, decided to output
@@ -10608,7 +10625,7 @@ gen_subprogram_die (tree decl, dw_die_re
we'll get back to the abstract instance when done with the class. */
/* The class-scope declaration DIE must be the primary DIE. */
- if (origin && declaration && class_scope_p (context_die))
+ if (origin && declaration && class_or_namespace_scope_p (context_die))
{
origin = NULL;
if (old_die)
@@ -10873,7 +10890,7 @@ gen_variable_die (tree decl, dw_die_ref
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (DECL_EXTERNAL (decl)
- || class_scope_p (context_die));
+ || class_or_namespace_scope_p (context_die));
if (origin != NULL)
add_abstract_origin_attribute (var_die, origin);
@@ -10926,7 +10943,7 @@ gen_variable_die (tree decl, dw_die_ref
if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1);
- if (class_scope_p (context_die) || DECL_ABSTRACT (decl))
+ if (class_or_namespace_scope_p (context_die) || DECL_ABSTRACT (decl))
equate_decl_number_to_die (decl, var_die);
if (! declaration && ! DECL_ABSTRACT (decl))
@@ -11803,6 +11820,84 @@ is_redundant_typedef (tree decl)
return 0;
}
+/* Force out any required namespaces to be able to output DECL,
+ and return the new context_die for it, if it's changed. */
+static dw_die_ref
+setup_namespace_context (tree decl, dw_die_ref context_die)
+{
+ /* Force out the namespace. */
+ if (!DECL_ABSTRACT (decl) && 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 (tree decl, 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,
+ scope_die_for_namespace (context_die),
+ decl);
+ /* Anonymous namespaces shouldn't have a DW_AT_name. */
+ if (DECL_NAME (decl) == anonymous_namespace_name)
+ add_src_coords_attributes (namespace_die, decl);
+ else
+ 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);
+ }
+}
+
+/* Find the proper scope for a namespace die if the current context is
+ CONTEXT_DIE. */
+
+static dw_die_ref
+scope_die_for_namespace (dw_die_ref context_die)
+{
+ if (context_die->die_tag == DW_TAG_namespace)
+ return context_die;
+ else
+ return comp_unit_die;
+}
+
/* Generate Dwarf debug information for a decl described by DECL. */
static void
@@ -11838,7 +11933,7 @@ gen_decl_die (tree decl, dw_die_ref cont
emit info for the abstract instance and set up to refer to it. */
else if (cgraph_function_possibly_inlined_p (decl)
&& ! DECL_ABSTRACT (decl)
- && ! class_scope_p (context_die)
+ && ! class_or_namespace_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just
a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */
@@ -11851,6 +11946,8 @@ gen_decl_die (tree decl, dw_die_ref cont
/* Otherwise we're emitting the primary DIE for this decl. */
else if (debug_info_level > DINFO_LEVEL_TERSE)
{
+ context_die = setup_namespace_context (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);
@@ -11874,7 +11971,7 @@ gen_decl_die (tree decl, dw_die_ref cont
actual typedefs. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
-
+ context_die = setup_namespace_context (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
@@ -11904,6 +12001,7 @@ gen_decl_die (tree decl, dw_die_ref cont
variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
+ context_die = setup_namespace_context (decl, context_die);
/* Output any DIEs that are needed to specify the type of this data
object. */
@@ -11931,6 +12029,7 @@ gen_decl_die (tree decl, dw_die_ref cont
if (DECL_NAME (decl) != NULL_TREE
|| TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE)
{
+ context_die = setup_namespace_context (decl, context_die);
gen_type_die (member_declared_type (decl), context_die);
gen_field_die (decl, context_die);
}
@@ -11942,7 +12041,8 @@ gen_decl_die (tree decl, dw_die_ref cont
break;
case NAMESPACE_DECL:
- /* Ignore for now. */
+ context_die = setup_namespace_context (decl, context_die);
+ gen_namespace_die (decl, context_die);
break;
default:
@@ -12065,6 +12165,13 @@ dwarf2out_decl (tree decl)
return;
break;
+ case NAMESPACE_DECL:
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+ if (lookup_decl_die (decl) != NULL)
+ return;
+ break;
+
case TYPE_DECL:
/* Don't emit stubs for types unless they are needed by other DIEs. */
if (TYPE_DECL_SUPPRESS_DEBUG (decl))
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.338
diff -u -3 -p -r1.338 tree.c
--- tree.c 14 Nov 2003 08:19:59 -0000 1.338
+++ tree.c 1 Dec 2003 03:29:22 -0000
@@ -74,6 +74,11 @@ static const char * const tree_node_kind
};
#endif /* GATHER_STATISTICS */
+
+/* The name of the anonymous namespace, throughout this translation
+ unit. */
+tree anonymous_namespace_name;
+
/* Unique id for next decl created. */
static GTY(()) int next_decl_uid;
/* Unique id for next type created. */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.453
diff -u -3 -p -r1.453 tree.h
--- tree.h 14 Nov 2003 08:19:59 -0000 1.453
+++ tree.h 1 Dec 2003 03:29:23 -0000
@@ -3109,5 +3109,5 @@ typedef enum
extern int tree_node_counts[];
extern int tree_node_sizes[];
-
+extern GTY(()) tree anonymous_namespace_name;
#endif /* GCC_TREE_H */
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1157
diff -u -3 -p -r1.1157 decl.c
--- cp/decl.c 22 Nov 2003 06:49:18 -0000 1.1157
+++ cp/decl.c 1 Dec 2003 03:29:28 -0000
@@ -228,9 +228,6 @@ struct named_label_list GTY(())
#define named_labels cp_function_chain->x_named_labels
-/* The name of the anonymous namespace, throughout this translation
- unit. */
-tree anonymous_namespace_name;
/* The number of function bodies which we are currently processing.
(Zero if we are at namespace scope, one inside the body of a
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.934
diff -u -3 -p -r1.934 cp-tree.h
--- cp/cp-tree.h 22 Nov 2003 06:49:17 -0000 1.934
+++ cp/cp-tree.h 1 Dec 2003 03:29:30 -0000
@@ -3085,7 +3085,6 @@ extern GTY(()) tree error_mark_list;
extern GTY(()) tree integer_two_node;
extern GTY(()) tree integer_three_node;
-extern GTY(()) tree anonymous_namespace_name;
/* The number of function bodies which we are currently processing.
(Zero if we are at namespace scope, one inside the body of a
More information about the Gcc-patches
mailing list