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]
Other format: [Raw text]

[PATCH]: Generate namespace info for dwarf2


Here's an updated namespace patch that incorporates Jason's comments from
last year. :P

It's bootstrapping now. Okay to commit assuming bootstrap/regtest
succeeds?

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	30 Nov 2003 16:32:37 -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_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.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	30 Nov 2003 16:32:38 -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/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	30 Nov 2003 16:32:39 -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
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	30 Nov 2003 16:32:42 -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]