Commit 1f16b47c by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/35896 (gfortran TLS symbols broken with debug info)

	PR debug/35896
	* dwarf2out.c (dw_expand_expr, common_check): Removed.
	(fortran_common): New function.
	(gen_variable_die): Call fortran_common instead of common_check,
	adjust for it returning tree instead of rtx.    Formatting.

From-SVN: r135060
parent 4218dc2d
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
* tree-parloops.c (create_parallel_loop): Set OMP_RETURN_NOWAIT * tree-parloops.c (create_parallel_loop): Set OMP_RETURN_NOWAIT
on OMP_RETURN for OMP_FOR. on OMP_RETURN for OMP_FOR.
PR debug/35896
* dwarf2out.c (dw_expand_expr, common_check): Removed.
(fortran_common): New function.
(gen_variable_die): Call fortran_common instead of common_check,
adjust for it returning tree instead of rtx. Formatting.
2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com> 2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com>
PATCH rtl/7335 PATCH rtl/7335
......
...@@ -10527,63 +10527,6 @@ rtl_for_decl_init (tree init, tree type) ...@@ -10527,63 +10527,6 @@ rtl_for_decl_init (tree init, tree type)
return rtl; return rtl;
} }
/* This is a specialized subset of expand_expr to evaluate a DECL_VALUE_EXPR.
We stop if we find decls that haven't been expanded, or if the expression is
getting so complex we won't be able to represent it anyway. Returns NULL on
failure. */
static rtx
dw_expand_expr (tree expr)
{
switch (TREE_CODE (expr))
{
case VAR_DECL:
case PARM_DECL:
if (DECL_HAS_VALUE_EXPR_P (expr))
return dw_expand_expr (DECL_VALUE_EXPR (expr));
/* FALLTHRU */
case CONST_DECL:
case RESULT_DECL:
return DECL_RTL_IF_SET (expr);
case INTEGER_CST:
return expand_expr (expr, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
case COMPONENT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
case BIT_FIELD_REF:
{
enum machine_mode mode;
HOST_WIDE_INT bitsize, bitpos;
tree offset, tem;
int volatilep = 0, unsignedp = 0;
rtx x;
tem = get_inner_reference (expr, &bitsize, &bitpos, &offset,
&mode, &unsignedp, &volatilep, true);
x = dw_expand_expr (tem);
if (x == NULL || !MEM_P (x))
return NULL;
if (offset != NULL)
{
if (!host_integerp (offset, 0))
return NULL;
x = adjust_address_nv (x, mode, tree_low_cst (offset, 0));
}
if (bitpos != 0)
x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT);
return x;
}
default:
return NULL;
}
}
/* Generate RTL for the variable DECL to represent its location. */ /* Generate RTL for the variable DECL to represent its location. */
static rtx static rtx
...@@ -10820,86 +10763,50 @@ secname_for_decl (const_tree decl) ...@@ -10820,86 +10763,50 @@ secname_for_decl (const_tree decl)
If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the
value is the offset into the common block for the symbol. */ value is the offset into the common block for the symbol. */
static rtx static tree
common_check (tree decl, HOST_WIDE_INT *value) fortran_common (tree decl, HOST_WIDE_INT *value)
{ {
rtx home; tree val_expr, cvar;
rtx sym_addr; enum machine_mode mode;
rtx res = NULL_RTX; HOST_WIDE_INT bitsize, bitpos;
tree offset;
int volatilep = 0, unsignedp = 0;
/* If the decl isn't a VAR_DECL, or if it isn't public or static, or if /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
it does not have a value (the offset into the common area), or if it it does not have a value (the offset into the common area), or if it
is thread local (as opposed to global) then it isn't common, and shouldn't is thread local (as opposed to global) then it isn't common, and shouldn't
be handled as such. */ be handled as such. */
if (TREE_CODE (decl) != VAR_DECL if (TREE_CODE (decl) != VAR_DECL
|| !TREE_PUBLIC(decl) || !TREE_PUBLIC (decl)
|| !TREE_STATIC(decl) || !TREE_STATIC (decl)
|| !DECL_HAS_VALUE_EXPR_P(decl) || !DECL_HAS_VALUE_EXPR_P (decl)
|| DECL_THREAD_LOCAL_P (decl) || !is_fortran ())
|| !is_fortran()) return NULL_TREE;
return NULL;
home = DECL_RTL (decl);
if (home == NULL_RTX || GET_CODE (home) != MEM)
return NULL;
sym_addr = dw_expand_expr (DECL_VALUE_EXPR (decl));
if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM)
return NULL;
sym_addr = XEXP (sym_addr, 0);
if (GET_CODE (sym_addr) == CONST)
sym_addr = XEXP (sym_addr, 0);
if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS)
&& DECL_INITIAL (decl) == 0)
{
/* We have a sym that will go into a common area, meaning that it val_expr = DECL_VALUE_EXPR (decl);
will get storage reserved with a .comm/.lcomm assembler pseudo-op. if (TREE_CODE (val_expr) != COMPONENT_REF)
return NULL_TREE;
Determine name of common area this symbol will be an offset into, cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
and offset into that area. Also retrieve the decl for the area &mode, &unsignedp, &volatilep, true);
that the symbol is offset into. */
tree cdecl = NULL;
switch (GET_CODE (sym_addr)) if (cvar == NULL_TREE
{ || TREE_CODE (cvar) != VAR_DECL
case PLUS: || DECL_ARTIFICIAL (cvar)
if (GET_CODE (XEXP (sym_addr, 0)) == CONST_INT) || !TREE_PUBLIC (cvar))
{ return NULL_TREE;
res = XEXP (sym_addr, 1);
*value = INTVAL (XEXP (sym_addr, 0));
cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
}
else
{
res = XEXP (sym_addr, 0);
*value = INTVAL (XEXP (sym_addr, 1));
cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
}
break;
case SYMBOL_REF:
res = sym_addr;
*value = 0; *value = 0;
cdecl = SYMBOL_REF_DECL (sym_addr); if (offset != NULL)
break; {
if (!host_integerp (offset, 0))
default: return NULL_TREE;
error ("common symbol debug info is not structured as " *value = tree_low_cst (offset, 0);
"symbol+offset");
}
/* Check area common symbol is offset into. If this is not public, then
it is not a symbol in a common block. It must be a .lcomm symbol, not
a .comm symbol. */
if (cdecl == NULL || !TREE_PUBLIC(cdecl))
res = NULL_RTX;
} }
else if (bitpos != 0)
res = NULL_RTX; *value += bitpos / BITS_PER_UNIT;
return res; return cvar;
} }
...@@ -12800,7 +12707,7 @@ static void ...@@ -12800,7 +12707,7 @@ static void
gen_variable_die (tree decl, dw_die_ref context_die) gen_variable_die (tree decl, dw_die_ref context_die)
{ {
HOST_WIDE_INT off; HOST_WIDE_INT off;
rtx csym; tree com_decl;
dw_die_ref var_die; dw_die_ref var_die;
tree origin = decl_ultimate_origin (decl); tree origin = decl_ultimate_origin (decl);
dw_die_ref old_die = lookup_decl_die (decl); dw_die_ref old_die = lookup_decl_die (decl);
...@@ -12826,31 +12733,31 @@ gen_variable_die (tree decl, dw_die_ref context_die) ...@@ -12826,31 +12733,31 @@ gen_variable_die (tree decl, dw_die_ref context_die)
&& DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl)) && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
|| class_or_namespace_scope_p (context_die)); || class_or_namespace_scope_p (context_die));
csym = common_check (decl, &off); com_decl = fortran_common (decl, &off);
/* Symbol in common gets emitted as a child of the common block, in the form /* Symbol in common gets emitted as a child of the common block, in the form
of a data member. of a data member.
??? This creates a new common block die for every common block symbol. ??? This creates a new common block die for every common block symbol.
Better to share same common block die for all symbols in that block. */ Better to share same common block die for all symbols in that block. */
if (csym) if (com_decl)
{ {
tree blok; tree field;
dw_die_ref com_die; dw_die_ref com_die;
const char *cnam = targetm.strip_name_encoding(XSTR (csym, 0)); const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
dw_loc_descr_ref loc = mem_loc_descriptor (csym, dw_val_class_addr, dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
VAR_INIT_STATUS_INITIALIZED);
blok = (tree) TREE_OPERAND (DECL_VALUE_EXPR (decl), 0); field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
var_die = new_die (DW_TAG_common_block, context_die, decl); var_die = new_die (DW_TAG_common_block, context_die, decl);
add_name_and_src_coords_attributes (var_die, blok); add_name_and_src_coords_attributes (var_die, field);
add_AT_flag (var_die, DW_AT_external, 1); add_AT_flag (var_die, DW_AT_external, 1);
add_AT_loc (var_die, DW_AT_location, loc); add_AT_loc (var_die, DW_AT_location, loc);
com_die = new_die (DW_TAG_member, var_die, decl); com_die = new_die (DW_TAG_member, var_die, decl);
add_name_and_src_coords_attributes (com_die, decl); add_name_and_src_coords_attributes (com_die, decl);
add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl), add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
TREE_THIS_VOLATILE (decl), context_die); TREE_THIS_VOLATILE (decl), context_die);
add_AT_loc (com_die, DW_AT_data_member_location, int_loc_descriptor(off)); add_AT_loc (com_die, DW_AT_data_member_location,
int_loc_descriptor (off));
add_pubname_string (cnam, var_die); /* ??? needed? */ add_pubname_string (cnam, var_die); /* ??? needed? */
return; return;
} }
......
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