aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1997-09-15 22:39:46 -0600
committerJeff Law <law@gcc.gnu.org>1997-09-15 22:39:46 -0600
commit4401bf245c6e45a270187245ef0e75bf7f706012 (patch)
treedbc300dd68d894385ceb694f09b48927e72f4cbf /gcc
parent33687242dc84a47422a1f3cd4903d8004d613055 (diff)
downloadgcc-4401bf245c6e45a270187245ef0e75bf7f706012.zip
gcc-4401bf245c6e45a270187245ef0e75bf7f706012.tar.gz
gcc-4401bf245c6e45a270187245ef0e75bf7f706012.tar.bz2
dwarf2out.c (gen_subprogram_die): Handle redefinition of an extern inline function.
* dwarf2out.c (gen_subprogram_die): Handle redefinition of an extern inline function. * dwarf2out.c (reg_loc_descriptor): Fix prototype. (concat_loc_descriptor): New function. (loc_descriptor): Call it. (add_AT_location_description): Also elide the descriptor if both halves of a CONCAT are pseudos. (add_location_or_const_value_attribute): Recognize CONCAT too. Bring over from devo/fsf. From-SVN: r15470
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/dwarf2out.c52
2 files changed, 64 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca793d5..1f98c85 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+Mon Sep 15 22:40:55 1997 Jim Wilson (wilson@cygnus.com)
+
+ * dwarf2out.c (gen_subprogram_die): Handle redefinition of an
+ extern inline function.
+
+Mon Sep 15 22:40:55 1997 Richard Henderson (rth@cygnus.com)
+
+ * dwarf2out.c (reg_loc_descriptor): Fix prototype.
+ (concat_loc_descriptor): New function.
+ (loc_descriptor): Call it.
+ (add_AT_location_description): Also elide the descriptor if both
+ halves of a CONCAT are pseudos.
+ (add_location_or_const_value_attribute): Recognize CONCAT too.
+
Mon Sep 15 15:24:00 1997 Richard Henderson <rth@cygnus.com>
* alpha.md (movdi): Handle CONST_DOUBLE for TARGET_BUILD_CONSTANTS.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6789f01..1b7548d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -2163,10 +2163,11 @@ static tree root_type PROTO((tree));
static int is_base_type PROTO((tree));
static dw_die_ref modified_type_die PROTO((tree, int, int, dw_die_ref));
static int type_is_enum PROTO((tree));
-static dw_loc_descr_ref reg_loc_descr_ref PROTO((rtx));
+static dw_loc_descr_ref reg_loc_descriptor PROTO((rtx));
static dw_loc_descr_ref based_loc_descr PROTO((unsigned, long));
static int is_based_loc PROTO((rtx));
static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx));
+static dw_loc_descr_ref concat_loc_descriptor PROTO((rtx, rtx));
static dw_loc_descr_ref loc_descriptor PROTO((rtx));
static unsigned ceiling PROTO((unsigned, unsigned));
static tree field_type PROTO((tree));
@@ -6188,6 +6189,30 @@ mem_loc_descriptor (rtl)
return mem_loc_result;
}
+/* Return a descriptor that describes the concatination of two locations.
+ This is typically a complex variable. */
+
+static dw_loc_descr_ref
+concat_loc_descriptor (x0, x1)
+ register rtx x0, x1;
+{
+ dw_loc_descr_ref cc_loc_result = NULL;
+
+ if (!is_pseudo_reg (x0)
+ && (GET_CODE (x0) != MEM || !is_pseudo_reg (XEXP (x0, 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)
+ && (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,
+ new_loc_descr (DW_OP_piece, GET_MODE_SIZE (GET_MODE (x1)), 0));
+
+ return cc_loc_result;
+}
+
/* Output a proper Dwarf location descriptor for a variable or parameter
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
@@ -6219,6 +6244,10 @@ loc_descriptor (rtl)
loc_result = mem_loc_descriptor (XEXP (rtl, 0));
break;
+ case CONCAT:
+ loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
+ break;
+
default:
abort ();
}
@@ -6426,7 +6455,10 @@ add_AT_location_description (die, attr_kind, rtl)
if (is_pseudo_reg (rtl)
|| (GET_CODE (rtl) == MEM
- && is_pseudo_reg (XEXP (rtl, 0))))
+ && is_pseudo_reg (XEXP (rtl, 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));
@@ -6724,6 +6756,7 @@ add_location_or_const_value_attribute (die, decl)
case MEM:
case REG:
case SUBREG:
+ case CONCAT:
add_AT_location_description (die, DW_AT_location, rtl);
break;
@@ -7684,6 +7717,17 @@ gen_subprogram_die (decl, context_die)
subr_die = new_die (DW_TAG_subprogram, context_die);
add_abstract_origin_attribute (subr_die, origin);
}
+ else if (old_die && DECL_ABSTRACT (decl)
+ && get_AT_unsigned (old_die, DW_AT_inline))
+ {
+ /* This must be a redefinition of an extern inline function.
+ We can just reuse the old die here. */
+ subr_die = old_die;
+
+ /* Clear out the inlined attribute and parm types. */
+ remove_AT (subr_die, DW_AT_inline);
+ remove_children (subr_die);
+ }
else if (old_die)
{
register unsigned file_index
@@ -7768,6 +7812,10 @@ gen_subprogram_die (decl, context_die)
}
else if (DECL_ABSTRACT (decl))
{
+ /* ??? Checking DECL_DEFER_OUTPUT is correct for static inline functions,
+ but not for extern inline functions. We can't get this completely
+ correct because information about whether the function was declared
+ inline is not saved anywhere. */
if (DECL_DEFER_OUTPUT (decl))
{
if (DECL_INLINE (decl))