Commit 3c46c513 by Daniel Berlin Committed by Daniel Berlin

re PR debug/19124 (gcc generates incorrect dwarf2 debug info)

2005-01-20  Daniel Berlin  <dberlin@dberlin.org>

	Fix PR debug/19124
	* dwarf2out.c (concat_loc_descriptor): We don't know we can use
	fbreg, so we have to assume we can't.
	(loc_descriptor_from_tree_1): Ditto.
	(containing_function_has_frame_base): New function.
	(add_location_or_const_value_attribute): Use it.
	Also try to generate a frame_base from a single element location
	list.

From-SVN: r93979
parent 23ab2e4e
2005-01-20 Daniel Berlin <dberlin@dberlin.org>
Fix PR debug/19124
* dwarf2out.c (concat_loc_descriptor): We don't know we can use
fbreg, so we have to assume we can't.
(loc_descriptor_from_tree_1): Ditto.
(containing_function_has_frame_base): New function.
(add_location_or_const_value_attribute): Use it.
Also try to generate a frame_base from a single element location
list.
2005-01-20 Kazu Hirata <kazu@cs.umass.edu> 2005-01-20 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/15349 PR tree-optimization/15349
......
...@@ -8714,8 +8714,8 @@ static dw_loc_descr_ref ...@@ -8714,8 +8714,8 @@ static dw_loc_descr_ref
concat_loc_descriptor (rtx x0, rtx x1) concat_loc_descriptor (rtx x0, rtx x1)
{ {
dw_loc_descr_ref cc_loc_result = NULL; dw_loc_descr_ref cc_loc_result = NULL;
dw_loc_descr_ref x0_ref = loc_descriptor (x0, true); dw_loc_descr_ref x0_ref = loc_descriptor (x0, false);
dw_loc_descr_ref x1_ref = loc_descriptor (x1, true); dw_loc_descr_ref x1_ref = loc_descriptor (x1, false);
if (x0_ref == 0 || x1_ref == 0) if (x0_ref == 0 || x1_ref == 0)
return 0; return 0;
...@@ -8934,7 +8934,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address) ...@@ -8934,7 +8934,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
/* Certain constructs can only be represented at top-level. */ /* Certain constructs can only be represented at top-level. */
if (want_address == 2) if (want_address == 2)
return loc_descriptor (rtl, true); return loc_descriptor (rtl, false);
mode = GET_MODE (rtl); mode = GET_MODE (rtl);
if (MEM_P (rtl)) if (MEM_P (rtl))
...@@ -8942,7 +8942,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address) ...@@ -8942,7 +8942,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
rtl = XEXP (rtl, 0); rtl = XEXP (rtl, 0);
have_address = 1; have_address = 1;
} }
ret = mem_loc_descriptor (rtl, mode, true); ret = mem_loc_descriptor (rtl, mode, false);
} }
} }
break; break;
...@@ -9021,7 +9021,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address) ...@@ -9021,7 +9021,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
return 0; return 0;
mode = GET_MODE (rtl); mode = GET_MODE (rtl);
rtl = XEXP (rtl, 0); rtl = XEXP (rtl, 0);
ret = mem_loc_descriptor (rtl, mode, true); ret = mem_loc_descriptor (rtl, mode, false);
have_address = 1; have_address = 1;
break; break;
} }
...@@ -9971,6 +9971,29 @@ rtl_for_decl_location (tree decl) ...@@ -9971,6 +9971,29 @@ rtl_for_decl_location (tree decl)
return rtl; return rtl;
} }
/* Return true if DECL's containing function has a frame base attribute.
Return false otherwise. */
static bool
containing_function_has_frame_base (tree decl)
{
tree declcontext = decl_function_context (decl);
dw_die_ref context;
dw_attr_ref attr;
if (!declcontext)
return false;
context = lookup_decl_die (declcontext);
if (!context)
return false;
for (attr = context->die_attr; attr; attr = attr->dw_attr_next)
if (attr->dw_attr == DW_AT_frame_base)
return true;
return false;
}
/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value /* 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 data attribute for a variable or a parameter. We generate the
DW_AT_const_value attribute only in those cases where the given variable DW_AT_const_value attribute only in those cases where the given variable
...@@ -9989,12 +10012,15 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -9989,12 +10012,15 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
rtx rtl; rtx rtl;
dw_loc_descr_ref descr; dw_loc_descr_ref descr;
var_loc_list *loc_list; var_loc_list *loc_list;
bool can_use_fb;
struct var_loc_node *node;
if (TREE_CODE (decl) == ERROR_MARK) if (TREE_CODE (decl) == ERROR_MARK)
return; return;
gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == RESULT_DECL); || TREE_CODE (decl) == RESULT_DECL);
can_use_fb = containing_function_has_frame_base (decl);
/* See if we possibly have multiple locations for this variable. */ /* See if we possibly have multiple locations for this variable. */
loc_list = lookup_decl_loc (decl); loc_list = lookup_decl_loc (decl);
...@@ -10007,7 +10033,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -10007,7 +10033,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
const char *endname; const char *endname;
dw_loc_list_ref list; dw_loc_list_ref list;
rtx varloc; rtx varloc;
struct var_loc_node *node;
/* We need to figure out what section we should use as the base /* We need to figure out what section we should use as the base
for the address ranges where a given location is valid. for the address ranges where a given location is valid.
...@@ -10046,7 +10072,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -10046,7 +10072,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
node = loc_list->first; node = loc_list->first;
varloc = NOTE_VAR_LOCATION (node->var_loc_note); varloc = NOTE_VAR_LOCATION (node->var_loc_note);
list = new_loc_list (loc_descriptor (varloc, attr != DW_AT_frame_base), list = new_loc_list (loc_descriptor (varloc, can_use_fb),
node->label, node->next->label, secname, 1); node->label, node->next->label, secname, 1);
node = node->next; node = node->next;
...@@ -10058,7 +10084,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -10058,7 +10084,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
varloc = NOTE_VAR_LOCATION (node->var_loc_note); varloc = NOTE_VAR_LOCATION (node->var_loc_note);
add_loc_descr_to_loc_list (&list, add_loc_descr_to_loc_list (&list,
loc_descriptor (varloc, loc_descriptor (varloc,
attr != DW_AT_frame_base), can_use_fb),
node->label, node->next->label, secname); node->label, node->next->label, secname);
} }
...@@ -10079,7 +10105,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -10079,7 +10105,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
} }
add_loc_descr_to_loc_list (&list, add_loc_descr_to_loc_list (&list,
loc_descriptor (varloc, loc_descriptor (varloc,
attr != DW_AT_frame_base), can_use_fb),
node->label, endname, secname); node->label, endname, secname);
} }
...@@ -10088,16 +10114,36 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -10088,16 +10114,36 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
return; return;
} }
/* Try to get some constant RTL for this decl, and use that as the value of
the location. */
rtl = rtl_for_decl_location (decl); rtl = rtl_for_decl_location (decl);
if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)) if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING))
{ {
add_const_value_attribute (die, rtl); add_const_value_attribute (die, rtl);
return; return;
} }
/* We couldn't get any rtl, and we had no >1 element location list, so try
directly generating the location description from the tree. */
descr = loc_descriptor_from_tree (decl); descr = loc_descriptor_from_tree (decl);
if (descr) if (descr)
add_AT_location_description (die, attr, descr); {
add_AT_location_description (die, attr, descr);
return;
}
/* Lastly, if we have tried to generate the location otherwise, and it
didn't work out (we wouldn't be here if we did), and we have a one entry
location list, try generating a location from that. */
if (loc_list && loc_list->first)
{
node = loc_list->first;
descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note),
can_use_fb);
if (descr)
add_AT_location_description (die, attr, descr);
}
} }
/* If we don't have a copy of this variable in memory for some reason (such /* If we don't have a copy of this variable in memory for some reason (such
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment