Blob Blame History Raw
2008-08-22  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (loc_by_reference): New function.
	(add_location_or_const_value_attribute): Use it.

--- gcc/dwarf2out.c.jj	2008-08-22 12:12:56.000000000 +0200
+++ gcc/dwarf2out.c	2008-08-22 13:39:21.000000000 +0200
@@ -10971,6 +10971,32 @@ fortran_common (tree decl, HOST_WIDE_INT
   return cvar;
 }
 
+/* Dereference a location expression LOC if DECL is passed by invisible
+   reference.  */
+
+static dw_loc_descr_ref
+loc_by_reference (dw_loc_descr_ref loc, tree decl)
+{
+  HOST_WIDE_INT size;
+  enum dwarf_location_atom op;
+
+  if (loc == NULL)
+    return NULL;
+
+  if ((TREE_CODE (decl) != PARM_DECL && TREE_CODE (decl) != RESULT_DECL)
+      || !DECL_BY_REFERENCE (decl))
+    return loc;
+
+  size = int_size_in_bytes (TREE_TYPE (decl));
+  if (size > DWARF2_ADDR_SIZE || size == -1)
+    return 0;
+  else if (size == DWARF2_ADDR_SIZE)
+    op = DW_OP_deref;
+  else
+    op = DW_OP_deref_size;
+  add_loc_descr (&loc, new_loc_descr (op, size, 0));
+  return loc;
+}
 
 /* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
    data attribute for a variable or a parameter.  We generate the
@@ -11029,8 +11055,8 @@ add_location_or_const_value_attribute (d
       else
 	initialized = VAR_INIT_STATUS_INITIALIZED;
 
-      list = new_loc_list (loc_descriptor (varloc, initialized),
-			   node->label, node->next->label, secname, 1);
+      descr = loc_by_reference (loc_descriptor (varloc, initialized), decl);
+      list = new_loc_list (descr, node->label, node->next->label, secname, 1);
       node = node->next;
 
       for (; node->next; node = node->next)
@@ -11041,8 +11067,9 @@ add_location_or_const_value_attribute (d
 	    enum var_init_status initialized =
 	      NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
 	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
-	    add_loc_descr_to_loc_list (&list, 
-				       loc_descriptor (varloc, initialized),
+	    descr = loc_by_reference (loc_descriptor (varloc, initialized),
+				      decl);
+	    add_loc_descr_to_loc_list (&list, descr,
 				       node->label, node->next->label, secname);
 	  }
 
@@ -11063,8 +11090,9 @@ add_location_or_const_value_attribute (d
 					   current_function_funcdef_no);
 	      endname = ggc_strdup (label_id);
 	    }
-	  add_loc_descr_to_loc_list (&list, 
-				     loc_descriptor (varloc, initialized),
+	  descr = loc_by_reference (loc_descriptor (varloc, initialized),
+				    decl);
+	  add_loc_descr_to_loc_list (&list, descr,
 				     node->label, endname, secname);
 	}
 
@@ -11094,6 +11122,7 @@ add_location_or_const_value_attribute (d
       descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note), status);
       if (descr)
 	{
+	  descr = loc_by_reference (descr, decl);
 	  add_AT_location_description (die, attr, descr);
 	  return;
 	}
@@ -11104,6 +11133,7 @@ add_location_or_const_value_attribute (d
   descr = loc_descriptor_from_tree (decl);
   if (descr)
     {
+      descr = loc_by_reference (descr, decl);
       add_AT_location_description (die, attr, descr);
       return;
     }