Patchwork Emit DW_AT_object_pointer (PR debug/45110)

login
register
mail settings
Submitter Jakub Jelinek
Date July 29, 2010, 1:04 p.m.
Message ID <20100729130421.GE18378@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/60258/
State New
Headers show

Comments

Jakub Jelinek - July 29, 2010, 1:04 p.m.
Hi!

This patch ensures that for methods we emit DW_AT_object_pointer
attribute referencing the this (self for ObjC) DW_TAG_formal_parameter.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-07-29  Jakub Jelinek  <jakub@redhat.com>

	PR debug/45110
	* dwarf2out.c (dwarf_attr_name): Handle DW_AT_object_pointer.
	(gen_formal_types_die): Add DW_AT_object_pointer in methods.
	(gen_subprogram_die): Likewise.  Remove it when removing declaration's
	formal parameters.
	(gen_decl_die): Change return type to dw_die_ref, return what
	gen_formal_parameter_die returned.


	Jakub
Jason Merrill - July 29, 2010, 2 p.m.
On 07/29/2010 09:04 AM, Jakub Jelinek wrote:
> 	(gen_decl_die): Change return type to dw_die_ref, return what
> 	gen_formal_parameter_die returned.

So now it returns the DIE only if the decl is a parm?  That seems 
inconsistent.  If you don't want to change things around to consistently 
return DIEs from gen_decl_die, I think it would be better to do a 
lookup_decl_die in order to add the attribute, or add it in 
gen_formal_parameter_die.

Jason
Jakub Jelinek - July 29, 2010, 2:10 p.m.
On Thu, Jul 29, 2010 at 10:00:45AM -0400, Jason Merrill wrote:
> On 07/29/2010 09:04 AM, Jakub Jelinek wrote:
> >	(gen_decl_die): Change return type to dw_die_ref, return what
> >	gen_formal_parameter_die returned.
> 
> So now it returns the DIE only if the decl is a parm?  That seems
> inconsistent.

Yeah, it is inconsistent.  I've started changing other parts of gen_decl_die,
but gave up after a while, because most of the functions it calls return
void also, and some of the indirectly called functions return void as well.

>  If you don't want to change things around to
> consistently return DIEs from gen_decl_die, I think it would be
> better to do a lookup_decl_die in order to add the attribute, or add
> it in gen_formal_parameter_die.

lookup_decl_die was the first thing I've tried, unfortunately that doesn't
work in DW_TAG_inlined_subroutine.  Though, looking at that again,
it seems the standard only allows DW_AT_object_pointer for
DW_TAG_subprogram, so perhaps lookup_decl_die would be ok.

	Jakub
Jakub Jelinek - July 29, 2010, 4:42 p.m.
On Thu, Jul 29, 2010 at 04:10:14PM +0200, Jakub Jelinek wrote:
> On Thu, Jul 29, 2010 at 10:00:45AM -0400, Jason Merrill wrote:
> > On 07/29/2010 09:04 AM, Jakub Jelinek wrote:
> > >	(gen_decl_die): Change return type to dw_die_ref, return what
> > >	gen_formal_parameter_die returned.
> > 
> > So now it returns the DIE only if the decl is a parm?  That seems
> > inconsistent.
> 
> Yeah, it is inconsistent.  I've started changing other parts of gen_decl_die,
> but gave up after a while, because most of the functions it calls return
> void also, and some of the indirectly called functions return void as well.
> 
> >  If you don't want to change things around to
> > consistently return DIEs from gen_decl_die, I think it would be
> > better to do a lookup_decl_die in order to add the attribute, or add
> > it in gen_formal_parameter_die.
> 
> lookup_decl_die was the first thing I've tried, unfortunately that doesn't
> work in DW_TAG_inlined_subroutine.  Though, looking at that again,
> it seems the standard only allows DW_AT_object_pointer for
> DW_TAG_subprogram, so perhaps lookup_decl_die would be ok.

Actually no, even for DW_TAG_subprogram that is an issue (e.g. if there is
an out of line copy of the inline method).

One option would be to duplicate those few lines from gen_decl_die in
gen_subprogram_die, in particular replace
	gen_decl_die (parm, NULL, subr_die);
call with:
	if (!DECL_IGNORED_P (parm))
	  {
	    if (DECL_BY_REFERENCE (parm))
	      gen_type_die (TREE_TYPE (TREE_TYPE (parm)), subr_die);
	    else
	      gen_type_die (TREE_TYPE (parm), subr_die);
	    parm_die
	      = gen_formal_parameter_die (parm, NULL,
					  true /* Emit name attribute.  */,
					  subr_die);
	    /* Handle first parm for METHOD_TYPE here... */
	  }

	Jakub
Jason Merrill - July 29, 2010, 4:50 p.m.
Hmm.  I guess go ahead with your original patch, just document the 
inconsistency in the comment for gen_decl_die.

Jason

Patch

--- gcc/dwarf2out.c.jj	2010-07-28 11:44:24.000000000 +0200
+++ gcc/dwarf2out.c	2010-07-29 10:21:15.000000000 +0200
@@ -6300,7 +6300,7 @@  static int is_redundant_typedef (const_t
 static bool is_naming_typedef_decl (const_tree);
 static inline dw_die_ref get_context_die (tree);
 static void gen_namespace_die (tree, dw_die_ref);
-static void gen_decl_die (tree, tree, dw_die_ref);
+static dw_die_ref gen_decl_die (tree, tree, dw_die_ref);
 static dw_die_ref force_decl_die (tree);
 static dw_die_ref force_type_die (tree);
 static dw_die_ref setup_namespace_context (tree, dw_die_ref);
@@ -6809,6 +6809,8 @@  dwarf_attr_name (unsigned int attr)
       return "DW_AT_call_file";
     case DW_AT_call_line:
       return "DW_AT_call_line";
+    case DW_AT_object_pointer:
+      return "DW_AT_object_pointer";
 
     case DW_AT_signature:
       return "DW_AT_signature";
@@ -18371,9 +18373,14 @@  gen_formal_types_die (tree function_or_m
       parm_die = gen_formal_parameter_die (formal_type, NULL,
 					   true /* Emit name attribute.  */,
 					   context_die);
-      if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
-	   && link == first_parm_type)
-	  || (arg && DECL_ARTIFICIAL (arg)))
+      if (TREE_CODE (function_or_method_type) == METHOD_TYPE
+	  && link == first_parm_type)
+	{
+	  add_AT_flag (parm_die, DW_AT_artificial, 1);
+	  if (dwarf_version >= 3 || !dwarf_strict)
+	    add_AT_die_ref (context_die, DW_AT_object_pointer, parm_die);
+	}
+      else if (arg && DECL_ARTIFICIAL (arg))
 	add_AT_flag (parm_die, DW_AT_artificial, 1);
 
       link = TREE_CHAIN (link);
@@ -18648,6 +18655,7 @@  gen_subprogram_die (tree decl, dw_die_re
 	     cases die that forced declaration die (e.g. TAG_imported_module)
 	     is one of the children that we do not want to remove.  */
 	  remove_AT (subr_die, DW_AT_declaration);
+	  remove_AT (subr_die, DW_AT_object_pointer);
 	  remove_child_TAG (subr_die, DW_TAG_formal_parameter);
 	}
       else
@@ -18886,7 +18894,14 @@  gen_subprogram_die (tree decl, dw_die_re
 					   &parm);
 	  else if (parm)
 	    {
-	      gen_decl_die (parm, NULL, subr_die);
+	      dw_die_ref parm_die = gen_decl_die (parm, NULL, subr_die);
+
+	      if (parm == DECL_ARGUMENTS (decl)
+		  && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
+		  && parm_die
+		  && (dwarf_version >= 3 || !dwarf_strict))
+		add_AT_die_ref (subr_die, DW_AT_object_pointer, parm_die);
+
 	      parm = DECL_CHAIN (parm);
 	    }
 
@@ -20435,14 +20450,14 @@  gen_namespace_die (tree decl, dw_die_ref
 
 /* Generate Dwarf debug information for a decl described by DECL.  */
 
-static void
+static dw_die_ref
 gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
 {
   tree decl_or_origin = decl ? decl : origin;
   tree class_origin = NULL, ultimate_origin;
 
   if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin))
-    return;
+    return NULL;
 
   switch (TREE_CODE (decl_or_origin))
     {
@@ -20613,10 +20628,9 @@  gen_decl_die (tree decl, tree origin, dw
 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
       else
 	gen_type_die (TREE_TYPE (decl_or_origin), context_die);
-      gen_formal_parameter_die (decl, origin,
-				true /* Emit name attribute.  */,
-				context_die);
-      break;
+      return gen_formal_parameter_die (decl, origin,
+				       true /* Emit name attribute.  */,
+				       context_die);
 
     case NAMESPACE_DECL:
     case IMPORTED_DECL:
@@ -20629,6 +20643,8 @@  gen_decl_die (tree decl, tree origin, dw
       gcc_assert ((int)TREE_CODE (decl) > NUM_TREE_CODES);
       break;
     }
+
+  return NULL;
 }
 
 /* Output debug information for global decl DECL.  Called from toplev.c after