dwarf2out.c (reg_number): Abort if pseudo.

* dwarf2out.c (reg_number): Abort if pseudo.
	(reg_loc_descriptor): Return 0 if pseudo.
	(is_based_loc): Return 0 if pseudo.
	(mem_loc_descriptor): Return 0 for pseudo and handle 0 return from
	recursive calls.
	(concat_loc_descriptor): Return 0 if either part's descriptor is 0.
	(loc_descriptor): Return 0 if can't find location and handle 0
	return from recursive calls.
	(loc_descriptor_from_tree): Likewise.
	Fix handling of indirect.
	Also return 0 for PLACEHOLDER_EXPR.
	Clean up COMPONENT_REF cases.
	(add_AT_location_descriptor): Simplify, but handle 0 return from
	loc_descriptor.
	(add_const_value_attribute): Avoid shift count warning.
	(add_bound_info): Remove test for PLACEHOLDER_EXPR here.
	Set comp_unit_die as context if not in function.

From-SVN: r46573
This commit is contained in:
Richard Kenner 2001-10-28 02:30:03 +00:00 committed by Richard Kenner
parent 6b7d57c7e7
commit e7af1d4538
2 changed files with 166 additions and 116 deletions

View File

@ -1,5 +1,23 @@
Sat Oct 27 17:32:04 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> Sat Oct 27 17:32:04 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* dwarf2out.c (reg_number): Abort if pseudo.
(reg_loc_descriptor): Return 0 if pseudo.
(is_based_loc): Return 0 if pseudo.
(mem_loc_descriptor): Return 0 for pseudo and handle 0 return from
recursive calls.
(concat_loc_descriptor): Return 0 if either part's descriptor is 0.
(loc_descriptor): Return 0 if can't find location and handle 0
return from recursive calls.
(loc_descriptor_from_tree): Likewise.
Fix handling of indirect.
Also return 0 for PLACEHOLDER_EXPR.
Clean up COMPONENT_REF cases.
(add_AT_location_descriptor): Simplify, but handle 0 return from
loc_descriptor.
(add_const_value_attribute): Avoid shift count warning.
(add_bound_info): Remove test for PLACEHOLDER_EXPR here.
Set comp_unit_die as context if not in function.
* config/mips/mips-protos.h: Break up long lines. * config/mips/mips-protos.h: Break up long lines.
Remove needless #ifdef/#endif blocks. Remove needless #ifdef/#endif blocks.
Don't declare functions declared in file made by genpreds or recog.h. Don't declare functions declared in file made by genpreds or recog.h.

View File

@ -7438,24 +7438,25 @@ reg_number (rtl)
unsigned regno = REGNO (rtl); unsigned regno = REGNO (rtl);
if (regno >= FIRST_PSEUDO_REGISTER) if (regno >= FIRST_PSEUDO_REGISTER)
{ abort ();
warning ("internal regno botch: regno = %d\n", regno);
regno = 0; return DBX_REGISTER_NUMBER (regno);
} }
regno = DBX_REGISTER_NUMBER (regno); /* Return a location descriptor that designates a machine register or
return regno; zero if there is no such. */
}
/* Return a location descriptor that designates a machine register. */
static dw_loc_descr_ref static dw_loc_descr_ref
reg_loc_descriptor (rtl) reg_loc_descriptor (rtl)
rtx rtl; rtx rtl;
{ {
dw_loc_descr_ref loc_result = NULL; dw_loc_descr_ref loc_result = NULL;
unsigned reg = reg_number (rtl); unsigned reg;
if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
return 0;
reg = reg_number (rtl);
if (reg <= 31) if (reg <= 31)
loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0); loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
else else
@ -7537,6 +7538,7 @@ is_based_loc (rtl)
{ {
return (GET_CODE (rtl) == PLUS return (GET_CODE (rtl) == PLUS
&& ((GET_CODE (XEXP (rtl, 0)) == REG && ((GET_CODE (XEXP (rtl, 0)) == REG
&& REGNO (XEXP (rtl, 0)) < FIRST_PSEUDO_REGISTER
&& GET_CODE (XEXP (rtl, 1)) == CONST_INT))); && GET_CODE (XEXP (rtl, 1)) == CONST_INT)));
} }
@ -7551,7 +7553,9 @@ is_based_loc (rtl)
it into Dwarf postfix code as it goes. it into Dwarf postfix code as it goes.
MODE is the mode of the memory reference, needed to handle some MODE is the mode of the memory reference, needed to handle some
autoincrement addressing modes. */ autoincrement addressing modes.
Return 0 if we can't represent the location. */
static dw_loc_descr_ref static dw_loc_descr_ref
mem_loc_descriptor (rtl, mode) mem_loc_descriptor (rtl, mode)
@ -7559,6 +7563,7 @@ mem_loc_descriptor (rtl, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
dw_loc_descr_ref mem_loc_result = NULL; dw_loc_descr_ref mem_loc_result = NULL;
/* Note that for a dynamically sized array, the location we will generate a /* Note that for a dynamically sized array, the location we will generate a
description of here will be the lowest numbered location which is description of here will be the lowest numbered location which is
actually within the array. That's *not* necessarily the same as the actually within the array. That's *not* necessarily the same as the
@ -7602,11 +7607,13 @@ mem_loc_descriptor (rtl, mode)
the object in question was allocated to a register (rather than in the object in question was allocated to a register (rather than in
memory) so DWARF consumers need to be aware of the subtle memory) so DWARF consumers need to be aware of the subtle
distinction between OP_REG and OP_BASEREG. */ distinction between OP_REG and OP_BASEREG. */
if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
mem_loc_result = based_loc_descr (reg_number (rtl), 0); mem_loc_result = based_loc_descr (reg_number (rtl), 0);
break; break;
case MEM: case MEM:
mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl)); mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
if (mem_loc_result != 0)
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0)); add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
break; break;
@ -7656,14 +7663,14 @@ mem_loc_descriptor (rtl, mode)
else else
{ {
mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode); mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
if (mem_loc_result == 0)
break;
if (GET_CODE (XEXP (rtl, 1)) == CONST_INT if (GET_CODE (XEXP (rtl, 1)) == CONST_INT
&& INTVAL (XEXP (rtl, 1)) >= 0) && INTVAL (XEXP (rtl, 1)) >= 0)
{
add_loc_descr (&mem_loc_result, add_loc_descr (&mem_loc_result,
new_loc_descr (DW_OP_plus_uconst, new_loc_descr (DW_OP_plus_uconst,
INTVAL (XEXP (rtl, 1)), 0)); INTVAL (XEXP (rtl, 1)), 0));
}
else else
{ {
add_loc_descr (&mem_loc_result, add_loc_descr (&mem_loc_result,
@ -7675,14 +7682,20 @@ mem_loc_descriptor (rtl, mode)
break; break;
case MULT: case MULT:
{
/* If a pseudo-reg is optimized away, it is possible for it to /* If a pseudo-reg is optimized away, it is possible for it to
be replaced with a MEM containing a multiply. */ be replaced with a MEM containing a multiply. */
add_loc_descr (&mem_loc_result, dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode);
mem_loc_descriptor (XEXP (rtl, 0), mode)); dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode);
add_loc_descr (&mem_loc_result,
mem_loc_descriptor (XEXP (rtl, 1), mode)); if (op0 == 0 || op1 == 0)
break;
mem_loc_result = op0;
add_loc_descr (&mem_loc_result, op1);
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0)); add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
break; break;
}
case CONST_INT: case CONST_INT:
mem_loc_result = int_loc_descriptor (INTVAL (rtl)); mem_loc_result = int_loc_descriptor (INTVAL (rtl));
@ -7703,18 +7716,21 @@ concat_loc_descriptor (x0, x1)
rtx x0, x1; rtx x0, 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);
dw_loc_descr_ref x1_ref = loc_descriptor (x1);
if (!is_pseudo_reg (x0) if (x0_ref == 0 || x1_ref == 0)
&& (GET_CODE (x0) != MEM || !is_pseudo_reg (XEXP (x0, 0)))) return 0;
add_loc_descr (&cc_loc_result, loc_descriptor (x0));
add_loc_descr (&cc_loc_result,
new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x0)), 0));
if (!is_pseudo_reg (x1) cc_loc_result = x0_ref;
&& (GET_CODE (x1) != MEM || !is_pseudo_reg (XEXP (x1, 0))))
add_loc_descr (&cc_loc_result, loc_descriptor (x1));
add_loc_descr (&cc_loc_result, add_loc_descr (&cc_loc_result,
new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x1)), 0)); new_loc_descr (DW_OP_piece,
GET_MODE_SIZE (GET_MODE (x0)), 0));
add_loc_descr (&cc_loc_result, x1_ref);
add_loc_descr (&cc_loc_result,
new_loc_descr (DW_OP_piece,
GET_MODE_SIZE (GET_MODE (x1)), 0));
return cc_loc_result; return cc_loc_result;
} }
@ -7723,13 +7739,16 @@ concat_loc_descriptor (x0, x1)
which is either allocated in a register or in a memory location. For a which is either allocated in a register or in a memory location. For a
register, we just generate an OP_REG and the register number. For a register, we just generate an OP_REG and the register number. For a
memory location we provide a Dwarf postfix expression describing how to memory location we provide a Dwarf postfix expression describing how to
generate the (dynamic) address of the object onto the address stack. */ generate the (dynamic) address of the object onto the address stack.
If we don't know how to describe it, return 0. */
static dw_loc_descr_ref static dw_loc_descr_ref
loc_descriptor (rtl) loc_descriptor (rtl)
rtx rtl; rtx rtl;
{ {
dw_loc_descr_ref loc_result = NULL; dw_loc_descr_ref loc_result = NULL;
switch (GET_CODE (rtl)) switch (GET_CODE (rtl))
{ {
case SUBREG: case SUBREG:
@ -7762,15 +7781,17 @@ loc_descriptor (rtl)
} }
/* Similar, but generate the descriptor from trees instead of rtl. /* Similar, but generate the descriptor from trees instead of rtl.
This comes up particularly with variable length arrays. */ This comes up particularly with variable length arrays. If ADDRESSP
is nonzero, we are looking for an address. Otherwise, we return a
value. If we can't find a value, return 0. */
static dw_loc_descr_ref static dw_loc_descr_ref
loc_descriptor_from_tree (loc, addressp) loc_descriptor_from_tree (loc, addressp)
tree loc; tree loc;
int addressp; int addressp;
{ {
dw_loc_descr_ref ret = NULL; dw_loc_descr_ref ret, ret1;
int indirect_size = 0; int indirect_p = 0;
int unsignedp = TREE_UNSIGNED (TREE_TYPE (loc)); int unsignedp = TREE_UNSIGNED (TREE_TYPE (loc));
enum dwarf_location_atom op; enum dwarf_location_atom op;
@ -7781,35 +7802,36 @@ loc_descriptor_from_tree (loc, addressp)
switch (TREE_CODE (loc)) switch (TREE_CODE (loc))
{ {
case ERROR_MARK: case ERROR_MARK:
break; return 0;
case WITH_RECORD_EXPR: case WITH_RECORD_EXPR:
case PLACEHOLDER_EXPR:
/* This case involves extracting fields from an object to determine the /* This case involves extracting fields from an object to determine the
position of other fields. We don't try to encode this here. The position of other fields. We don't try to encode this here. The
only user of this is Ada, which encodes the needed information using only user of this is Ada, which encodes the needed information using
the names of types. */ the names of types. */
return ret; return 0;
case VAR_DECL: case VAR_DECL:
case PARM_DECL: case PARM_DECL:
{ {
rtx rtl = rtl_for_decl_location (loc); rtx rtl = rtl_for_decl_location (loc);
enum machine_mode mode = DECL_MODE (loc); enum machine_mode mode = GET_MODE (rtl);
if (rtl == NULL_RTX) if (rtl == NULL_RTX)
break; return 0;
else if (CONSTANT_P (rtl)) else if (CONSTANT_P (rtl))
{ {
ret = new_loc_descr (DW_OP_addr, 0, 0); ret = new_loc_descr (DW_OP_addr, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_addr; ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
ret->dw_loc_oprnd1.v.val_addr = rtl; ret->dw_loc_oprnd1.v.val_addr = rtl;
indirect_size = GET_MODE_SIZE (mode); indirect_p = 1;
} }
else else
{ {
if (GET_CODE (rtl) == MEM) if (GET_CODE (rtl) == MEM)
{ {
indirect_size = GET_MODE_SIZE (mode); indirect_p = 1;
rtl = XEXP (rtl, 0); rtl = XEXP (rtl, 0);
} }
ret = mem_loc_descriptor (rtl, mode); ret = mem_loc_descriptor (rtl, mode);
@ -7819,7 +7841,7 @@ loc_descriptor_from_tree (loc, addressp)
case INDIRECT_REF: case INDIRECT_REF:
ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
indirect_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (loc))); indirect_p = 1;
break; break;
case NOP_EXPR: case NOP_EXPR:
@ -7841,7 +7863,15 @@ loc_descriptor_from_tree (loc, addressp)
obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode, obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
&unsignedp, &volatilep, &alignment); &unsignedp, &volatilep, &alignment);
if (obj == loc)
return 0;
ret = loc_descriptor_from_tree (obj, 1); ret = loc_descriptor_from_tree (obj, 1);
if (ret == 0
|| bitpos % BITS_PER_UNIT != 0
|| bitsize % BITS_PER_UNIT != 0)
return 0;
if (offset != NULL_TREE) if (offset != NULL_TREE)
{ {
@ -7850,24 +7880,8 @@ loc_descriptor_from_tree (loc, addressp)
add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0)); add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
} }
if (addressp) if (!addressp)
{ indirect_p = 1;
/* We cannot address anything not on a unit boundary. */
if (bitpos % BITS_PER_UNIT != 0)
abort ();
}
else
{
if (bitpos % BITS_PER_UNIT != 0
|| bitsize % BITS_PER_UNIT != 0)
{
/* ??? We could handle this by loading and shifting etc.
Wait until someone needs it before expending the effort. */
abort ();
}
indirect_size = bitsize / BITS_PER_UNIT;
}
bytepos = bitpos / BITS_PER_UNIT; bytepos = bitpos / BITS_PER_UNIT;
if (bytepos > 0) if (bytepos > 0)
@ -7883,40 +7897,54 @@ loc_descriptor_from_tree (loc, addressp)
case INTEGER_CST: case INTEGER_CST:
if (host_integerp (loc, 0)) if (host_integerp (loc, 0))
ret = int_loc_descriptor (tree_low_cst (loc, 0)); ret = int_loc_descriptor (tree_low_cst (loc, 0));
else
return 0;
break; break;
case BIT_AND_EXPR: case BIT_AND_EXPR:
op = DW_OP_and; op = DW_OP_and;
goto do_binop; goto do_binop;
case BIT_XOR_EXPR: case BIT_XOR_EXPR:
op = DW_OP_xor; op = DW_OP_xor;
goto do_binop; goto do_binop;
case BIT_IOR_EXPR: case BIT_IOR_EXPR:
op = DW_OP_or; op = DW_OP_or;
goto do_binop; goto do_binop;
case TRUNC_DIV_EXPR: case TRUNC_DIV_EXPR:
op = DW_OP_div; op = DW_OP_div;
goto do_binop; goto do_binop;
case MINUS_EXPR: case MINUS_EXPR:
op = DW_OP_minus; op = DW_OP_minus;
goto do_binop; goto do_binop;
case TRUNC_MOD_EXPR: case TRUNC_MOD_EXPR:
op = DW_OP_mod; op = DW_OP_mod;
goto do_binop; goto do_binop;
case MULT_EXPR: case MULT_EXPR:
op = DW_OP_mul; op = DW_OP_mul;
goto do_binop; goto do_binop;
case LSHIFT_EXPR: case LSHIFT_EXPR:
op = DW_OP_shl; op = DW_OP_shl;
goto do_binop; goto do_binop;
case RSHIFT_EXPR: case RSHIFT_EXPR:
op = (unsignedp ? DW_OP_shr : DW_OP_shra); op = (unsignedp ? DW_OP_shr : DW_OP_shra);
goto do_binop; goto do_binop;
case PLUS_EXPR: case PLUS_EXPR:
if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST
&& host_integerp (TREE_OPERAND (loc, 1), 0)) && host_integerp (TREE_OPERAND (loc, 1), 0))
{ {
ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
if (ret == 0)
return 0;
add_loc_descr (&ret, add_loc_descr (&ret,
new_loc_descr (DW_OP_plus_uconst, new_loc_descr (DW_OP_plus_uconst,
tree_low_cst (TREE_OPERAND (loc, 1), tree_low_cst (TREE_OPERAND (loc, 1),
@ -7924,53 +7952,72 @@ loc_descriptor_from_tree (loc, addressp)
0)); 0));
break; break;
} }
op = DW_OP_plus; op = DW_OP_plus;
goto do_binop; goto do_binop;
case LE_EXPR: case LE_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
break; return 0;
op = DW_OP_le; op = DW_OP_le;
goto do_binop; goto do_binop;
case GE_EXPR: case GE_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
break; return 0;
op = DW_OP_ge; op = DW_OP_ge;
goto do_binop; goto do_binop;
case LT_EXPR: case LT_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
break; return 0;
op = DW_OP_lt; op = DW_OP_lt;
goto do_binop; goto do_binop;
case GT_EXPR: case GT_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0)))) if (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
break; return 0;
op = DW_OP_gt; op = DW_OP_gt;
goto do_binop; goto do_binop;
case EQ_EXPR: case EQ_EXPR:
op = DW_OP_eq; op = DW_OP_eq;
goto do_binop; goto do_binop;
case NE_EXPR: case NE_EXPR:
op = DW_OP_ne; op = DW_OP_ne;
goto do_binop; goto do_binop;
do_binop: do_binop:
ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
add_loc_descr (&ret, loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0)); ret1 = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
if (ret == 0 || ret1 == 0)
return 0;
add_loc_descr (&ret, ret1);
add_loc_descr (&ret, new_loc_descr (op, 0, 0)); add_loc_descr (&ret, new_loc_descr (op, 0, 0));
break; break;
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
op = DW_OP_not; op = DW_OP_not;
goto do_unop; goto do_unop;
case ABS_EXPR: case ABS_EXPR:
op = DW_OP_abs; op = DW_OP_abs;
goto do_unop; goto do_unop;
case NEGATE_EXPR: case NEGATE_EXPR:
op = DW_OP_neg; op = DW_OP_neg;
goto do_unop; goto do_unop;
do_unop: do_unop:
ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
if (ret == 0)
return 0;
add_loc_descr (&ret, new_loc_descr (op, 0, 0)); add_loc_descr (&ret, new_loc_descr (op, 0, 0));
break; break;
@ -7983,21 +8030,26 @@ loc_descriptor_from_tree (loc, addressp)
case COND_EXPR: case COND_EXPR:
{ {
dw_loc_descr_ref lhs
= loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
dw_loc_descr_ref rhs
= loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0);
dw_loc_descr_ref bra_node, jump_node, tmp; dw_loc_descr_ref bra_node, jump_node, tmp;
ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0); ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
if (ret == 0 || lhs == 0 || rhs == 0)
return 0;
bra_node = new_loc_descr (DW_OP_bra, 0, 0); bra_node = new_loc_descr (DW_OP_bra, 0, 0);
add_loc_descr (&ret, bra_node); add_loc_descr (&ret, bra_node);
tmp = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0); add_loc_descr (&ret, rhs);
add_loc_descr (&ret, tmp);
jump_node = new_loc_descr (DW_OP_skip, 0, 0); jump_node = new_loc_descr (DW_OP_skip, 0, 0);
add_loc_descr (&ret, jump_node); add_loc_descr (&ret, jump_node);
tmp = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0); add_loc_descr (&ret, lhs);
add_loc_descr (&ret, tmp);
bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc; bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
bra_node->dw_loc_oprnd1.v.val_loc = tmp; bra_node->dw_loc_oprnd1.v.val_loc = lhs;
/* ??? Need a node to point the skip at. Use a nop. */ /* ??? Need a node to point the skip at. Use a nop. */
tmp = new_loc_descr (DW_OP_nop, 0, 0); tmp = new_loc_descr (DW_OP_nop, 0, 0);
@ -8011,20 +8063,23 @@ loc_descriptor_from_tree (loc, addressp)
abort (); abort ();
} }
/* If we can't fill the request for an address, die. */ /* Show if we can't fill the request for an address. */
if (addressp && indirect_size == 0) if (addressp && indirect_p == 0)
abort (); return 0;
/* If we've got an address and don't want one, dereference. */ /* If we've got an address and don't want one, dereference. */
if (!addressp && indirect_size > 0) if (!addressp && indirect_p > 0)
{ {
if (indirect_size > DWARF2_ADDR_SIZE) HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
abort ();
if (indirect_size == DWARF2_ADDR_SIZE) if (size > DWARF2_ADDR_SIZE || size == -1)
return 0;
if (size == DWARF2_ADDR_SIZE)
op = DW_OP_deref; op = DW_OP_deref;
else else
op = DW_OP_deref_size; op = DW_OP_deref_size;
add_loc_descr (&ret, new_loc_descr (op, indirect_size, 0));
add_loc_descr (&ret, new_loc_descr (op, size, 0));
} }
return ret; return ret;
@ -8240,31 +8295,10 @@ add_AT_location_description (die, attr_kind, rtl)
enum dwarf_attribute attr_kind; enum dwarf_attribute attr_kind;
rtx rtl; rtx rtl;
{ {
/* Handle a special case. If we are about to output a location descriptor dw_loc_descr_ref descr = loc_descriptor (rtl);
for a variable or parameter which has been optimized out of existence,
don't do that. A variable which has been optimized out
of existence will have a DECL_RTL value which denotes a pseudo-reg.
Currently, in some rare cases, variables can have DECL_RTL values which
look like (MEM (REG pseudo-reg#)). These cases are due to bugs
elsewhere in the compiler. We treat such cases as if the variable(s) in
question had been optimized out of existence. */
if (is_pseudo_reg (rtl) if (descr != 0)
|| (GET_CODE (rtl) == MEM add_AT_loc (die, attr_kind, descr);
&& is_pseudo_reg (XEXP (rtl, 0)))
/* This can happen for a PARM_DECL with a DECL_INCOMING_RTL which
references the internal argument pointer (a pseudo) in a function
where all references to the internal argument pointer were
eliminated via the optimizers. */
|| (GET_CODE (rtl) == MEM
&& GET_CODE (XEXP (rtl, 0)) == PLUS
&& is_pseudo_reg (XEXP (XEXP (rtl, 0), 0)))
|| (GET_CODE (rtl) == CONCAT
&& is_pseudo_reg (XEXP (rtl, 0))
&& is_pseudo_reg (XEXP (rtl, 1))))
return;
add_AT_loc (die, attr_kind, loc_descriptor (rtl));
} }
/* Attach the specialized form of location attribute used for data /* Attach the specialized form of location attribute used for data
@ -8343,11 +8377,12 @@ add_const_value_attribute (die, rtl)
add_AT_int (die, DW_AT_const_value, (long) val); add_AT_int (die, DW_AT_const_value, (long) val);
else if ((unsigned long) val == (unsigned HOST_WIDE_INT) val) else if ((unsigned long) val == (unsigned HOST_WIDE_INT) val)
add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val); add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val);
else if (2*HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT) #if HOST_BITS_PER_LONG * 2 == HOST_BITS_PER_WIDE_INT
add_AT_long_long (die, DW_AT_const_value, add_AT_long_long (die, DW_AT_const_value,
val >> HOST_BITS_PER_LONG, val); val >> HOST_BITS_PER_LONG, val);
else #else
abort (); abort ();
#endif
} }
break; break;
@ -8710,12 +8745,6 @@ add_bound_info (subrange_die, bound_attr, bound)
enum dwarf_attribute bound_attr; enum dwarf_attribute bound_attr;
tree bound; tree bound;
{ {
/* If this is an Ada unconstrained array type, then don't emit any debug
info because the array bounds are unknown. They are parameterized when
the type is instantiated. */
if (contains_placeholder_p (bound))
return;
switch (TREE_CODE (bound)) switch (TREE_CODE (bound))
{ {
case ERROR_MARK: case ERROR_MARK:
@ -8816,6 +8845,9 @@ add_bound_info (subrange_die, bound_attr, bound)
if (loc == NULL) if (loc == NULL)
break; break;
if (current_function_decl == 0)
ctx = comp_unit_die;
else
ctx = lookup_decl_die (current_function_decl); ctx = lookup_decl_die (current_function_decl);
decl_die = new_die (DW_TAG_variable, ctx); decl_die = new_die (DW_TAG_variable, ctx);