[debug-early] emit early dwarf for locally scoped functions
diff mbox

Message ID 55132325.9000700@redhat.com
State New
Headers show

Commit Message

Aldy Hernandez March 25, 2015, 9:05 p.m. UTC
On 03/25/2015 12:37 PM, Jason Merrill wrote:
> On 03/24/2015 02:00 PM, Aldy Hernandez wrote:
>> I found that for locally scoped functions we were not emitting early
>> dwarf.
>
> Why weren't they being emitted as part of their enclosing function? They
> should be.
>
> Jason
>

Hmm, you're right.  Sorry for being so sloppy.

What is actually happening is that when the declaration is seen, 
nameless DIEs for the types are generated, which are then used when the 
cached subprogram DIE is seen the second time.  The nameless DIEs end up 
looking like this because we don't have the "this" name:

     char Object_method(Object * const);

whereas the function type should be:

     char Object_method(void);

I now understand what this was doing in mainline:

	  /* Clear out the declaration attribute and the formal parameters.
	     Do not remove all children, because it is possible that this
	     declaration die was forced using force_decl_die(). In such
	     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);

I suppose we could re-use the DW_AT_object_pointer and 
DW_TAG_formal_parameter, and tack on the DW_AT_name now that we know it? 
  Or we could cheat and just remove them as mainline does, but only when 
reusing a declaration (as in the attached patch).

What do you think?

Aldy

Comments

Jason Merrill March 26, 2015, 2:07 a.m. UTC | #1
On 03/25/2015 05:05 PM, Aldy Hernandez wrote:
>   Or we could cheat and just remove them as mainline does, but only when
> reusing a declaration (as in the attached patch).

This seems right to me.

Jason
Aldy Hernandez March 26, 2015, 3:43 p.m. UTC | #2
On 03/25/2015 07:07 PM, Jason Merrill wrote:
> On 03/25/2015 05:05 PM, Aldy Hernandez wrote:
>>   Or we could cheat and just remove them as mainline does, but only when
>> reusing a declaration (as in the attached patch).
>
> This seems right to me.
>
> Jason
>
>

Ok thanks, committed.

Aldy

Patch
diff mbox

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 48e2eed..4bc945f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3113,7 +3113,7 @@  static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute);
 static bool is_cxx (void);
 static bool is_fortran (void);
 static bool is_ada (void);
-static void remove_AT (dw_die_ref, enum dwarf_attribute);
+static bool remove_AT (dw_die_ref, enum dwarf_attribute);
 static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
 static void add_child_die (dw_die_ref, dw_die_ref);
 static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
@@ -4752,16 +4752,17 @@  is_ada (void)
   return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
 }
 
-/* Remove the specified attribute if present.  */
+/* Remove the specified attribute if present.  Return TRUE if removal
+   was successful.  */
 
-static void
+static bool
 remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a;
   unsigned ix;
 
   if (! die)
-    return;
+    return false;
 
   FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
     if (a->dw_attr == attr_kind)
@@ -4773,8 +4774,9 @@  remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
 	/* vec::ordered_remove should help reduce the number of abbrevs
 	   that are needed.  */
 	die->die_attr->ordered_remove (ix);
-	return;
+	return true;
       }
+  return false;
 }
 
 /* Remove CHILD from its parent.  PREV must have the property that
@@ -18790,8 +18792,15 @@  gen_subprogram_die (tree decl, dw_die_ref context_die)
 
 	  /* Clear out the declaration attribute, but leave the
 	     parameters so they can be augmented with location
-	     information later.  */
-	  remove_AT (subr_die, DW_AT_declaration);
+	     information later.  Unless this was a declaration, in
+	     which case, wipe out the nameless parameters and recreate
+	     them further down.  */
+	  if (remove_AT (subr_die, DW_AT_declaration))
+	    {
+
+	      remove_AT (subr_die, DW_AT_object_pointer);
+	      remove_child_TAG (subr_die, DW_TAG_formal_parameter);
+	    }
 	}
       /* Make a specification pointing to the previously built
 	 declaration.  */