aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2010-09-09 08:43:47 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-09-09 08:43:47 +0200
commitc8a27c401821b4d29c28add396177637f9f381d5 (patch)
tree95afa643e40b04b8d3422e12829ab8707b957836 /gcc/dwarf2out.c
parenteed023ccd5bb3b3bc9690b79d18c645637527e43 (diff)
downloadgcc-c8a27c401821b4d29c28add396177637f9f381d5.zip
gcc-c8a27c401821b4d29c28add396177637f9f381d5.tar.gz
gcc-c8a27c401821b4d29c28add396177637f9f381d5.tar.bz2
rtl.def (DEBUG_IMPLICIT_PTR): New rtl code.
* rtl.def (DEBUG_IMPLICIT_PTR): New rtl code. * rtl.h (DEBUG_IMPLICIT_PTR_DECL): Define. * rtl.c (rtx_equal_p_cb, rtx_equal_p): Handle DEBUG_IMPLICIT_PTR. * print-rtl.c (print_rtx): Likewise. * cselib.c (rtx_equal_for_cselib_p, cselib_hash_rtx): Likewise. * cfgexpand.c (expand_debug_expr): Generate DEBUG_IMPLICIT_PTR for ADDR_EXPR with non-addressable object. * dwarf2out.c (enum dw_val_class): Add dw_val_class_decl_ref. (struct dw_val_struct): Add v.val_decl_ref. (dwarf_stack_op_name, output_loc_operands, output_loc_operands_raw): Handle DW_OP_GNU_implicit_pointer. (size_of_loc_descr): Likewise. Fix up DW_OP_call_ref size. (get_ref_die_offset_label): New function. (implicit_ptr_descriptor): New function. (mem_loc_descriptor): Handle DEBUG_IMPLICIT_PTR. (loc_descriptor): Likewise. (gen_variable_die): Put even definitions into decl_die_table. (resolve_addr_in_expr): Resolve still unresolved DW_OP_GNU_implicit_pointer operands, if it can't be resolved return false. (dwarf2out_finish): Call output_location_lists after outputting .debug_info and .debug_abbrev instead of before. * dwarf2.h (DW_OP_GNU_implicit_pointer): New. 2010-09-09 Roland McGrath <roland@redhat.com> * dwarf2out.c (DWARF_REF_SIZE): Define. (size_of_loc_descr): Use it for DW_OP_call_ref. From-SVN: r164050
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c115
1 files changed, 102 insertions, 13 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 237d089..11707fb 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4294,6 +4294,7 @@ enum dw_val_class
dw_val_class_macptr,
dw_val_class_file,
dw_val_class_data8,
+ dw_val_class_decl_ref,
dw_val_class_vms_delta
};
@@ -4332,6 +4333,7 @@ typedef struct GTY(()) dw_val_struct {
unsigned char GTY ((tag ("dw_val_class_flag"))) val_flag;
struct dwarf_file_data * GTY ((tag ("dw_val_class_file"))) val_file;
unsigned char GTY ((tag ("dw_val_class_data8"))) val_data8[8];
+ tree GTY ((tag ("dw_val_class_decl_ref"))) val_decl_ref;
struct dw_val_vms_delta_union
{
char * lbl1;
@@ -4695,6 +4697,8 @@ dwarf_stack_op_name (unsigned int op)
return "DW_OP_GNU_uninit";
case DW_OP_GNU_encoded_addr:
return "DW_OP_GNU_encoded_addr";
+ case DW_OP_GNU_implicit_pointer:
+ return "DW_OP_GNU_implicit_pointer";
default:
return "OP_<unknown>";
@@ -4798,6 +4802,9 @@ loc_list_plus_const (dw_loc_list_ref list_head, HOST_WIDE_INT offset)
loc_descr_plus_const (&d->expr, offset);
}
+#define DWARF_REF_SIZE \
+ (dwarf_version == 2 ? DWARF2_ADDR_SIZE : DWARF_OFFSET_SIZE)
+
/* Return the size of a location descriptor. */
static unsigned long
@@ -4904,12 +4911,15 @@ size_of_loc_descr (dw_loc_descr_ref loc)
size += 4;
break;
case DW_OP_call_ref:
- size += DWARF2_ADDR_SIZE;
+ size += DWARF_REF_SIZE;
break;
case DW_OP_implicit_value:
size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned)
+ loc->dw_loc_oprnd1.v.val_unsigned;
break;
+ case DW_OP_GNU_implicit_pointer:
+ size += DWARF_REF_SIZE + size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int);
+ break;
default:
break;
}
@@ -4946,6 +4956,7 @@ size_of_locs (dw_loc_descr_ref loc)
}
static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
+static void get_ref_die_offset_label (char *, dw_die_ref);
/* Output location description stack opcode's operands (if any). */
@@ -5165,6 +5176,17 @@ output_loc_operands (dw_loc_descr_ref loc)
}
break;
+ case DW_OP_GNU_implicit_pointer:
+ {
+ char label[MAX_ARTIFICIAL_LABEL_BYTES
+ + HOST_BITS_PER_WIDE_INT / 2 + 2];
+ gcc_assert (val1->val_class == dw_val_class_die_ref);
+ get_ref_die_offset_label (label, val1->v.val_die_ref.die);
+ dw2_asm_output_offset (DWARF_REF_SIZE, label, debug_info_section, NULL);
+ dw2_asm_output_data_sleb128 (val2->v.val_int, NULL);
+ }
+ break;
+
default:
/* Other codes have no operands. */
break;
@@ -5303,6 +5325,10 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
dw2_asm_output_data_sleb128_raw (val2->v.val_int);
break;
+ case DW_OP_GNU_implicit_pointer:
+ gcc_unreachable ();
+ break;
+
default:
/* Other codes have no operands. */
break;
@@ -6514,6 +6540,15 @@ is_tagged_type (const_tree type)
|| code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE);
}
+/* Set label to debug_info_section_label + die_offset of a DIE reference. */
+
+static void
+get_ref_die_offset_label (char *label, dw_die_ref ref)
+{
+ sprintf (label, "%s+" HOST_WIDE_INT_PRINT_DEC,
+ debug_info_section_label, ref->die_offset);
+}
+
/* Convert a DIE tag into its string name. */
static const char *
@@ -13651,6 +13686,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
case CONCAT:
case CONCATN:
case VAR_LOCATION:
+ case DEBUG_IMPLICIT_PTR:
expansion_failed (NULL_TREE, rtl,
"CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
return 0;
@@ -14240,6 +14276,35 @@ concatn_loc_descriptor (rtx concatn, enum var_init_status initialized)
return cc_loc_result;
}
+/* Helper function for loc_descriptor. Return DW_OP_GNU_implicit_pointer
+ for DEBUG_IMPLICIT_PTR RTL. */
+
+static dw_loc_descr_ref
+implicit_ptr_descriptor (rtx rtl, HOST_WIDE_INT offset)
+{
+ dw_loc_descr_ref ret;
+ dw_die_ref ref;
+
+ gcc_assert (TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == VAR_DECL
+ || TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == PARM_DECL
+ || TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == RESULT_DECL);
+ ref = lookup_decl_die (DEBUG_IMPLICIT_PTR_DECL (rtl));
+ ret = new_loc_descr (DW_OP_GNU_implicit_pointer, 0, offset);
+ ret->dw_loc_oprnd2.val_class = dw_val_class_const;
+ if (ref)
+ {
+ ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ ret->dw_loc_oprnd1.v.val_die_ref.die = ref;
+ ret->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ }
+ else
+ {
+ ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref;
+ ret->dw_loc_oprnd1.v.val_decl_ref = DEBUG_IMPLICIT_PTR_DECL (rtl);
+ }
+ return ret;
+}
+
/* 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
@@ -14457,6 +14522,19 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
}
break;
+ case DEBUG_IMPLICIT_PTR:
+ loc_result = implicit_ptr_descriptor (rtl, 0);
+ break;
+
+ case PLUS:
+ if (GET_CODE (XEXP (rtl, 0)) == DEBUG_IMPLICIT_PTR
+ && CONST_INT_P (XEXP (rtl, 1)))
+ {
+ loc_result
+ = implicit_ptr_descriptor (XEXP (rtl, 0), INTVAL (XEXP (rtl, 1)));
+ break;
+ }
+ /* FALLTHRU */
default:
if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE (rtl) == mode
&& GET_MODE_SIZE (GET_MODE (rtl)) <= DWARF2_ADDR_SIZE
@@ -19190,7 +19268,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1);
- if (decl && (DECL_ABSTRACT (decl) || declaration))
+ if (decl && (DECL_ABSTRACT (decl) || declaration || old_die == NULL))
equate_decl_number_to_die (decl, var_die);
if (! declaration
@@ -22150,6 +22228,17 @@ resolve_addr_in_expr (dw_loc_descr_ref loc)
&& loc->dw_loc_oprnd2.val_class == dw_val_class_addr
&& resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL)))
return false;
+ else if (loc->dw_loc_opc == DW_OP_GNU_implicit_pointer
+ && loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
+ {
+ dw_die_ref ref
+ = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref);
+ if (ref == NULL)
+ return false;
+ loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
+ loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ }
return true;
}
@@ -22429,17 +22518,6 @@ dwarf2out_finish (const char *filename)
add_ranges (NULL);
}
- /* Output location list section if necessary. */
- if (have_location_lists)
- {
- /* Output the location lists info. */
- switch_to_section (debug_loc_section);
- ASM_GENERATE_INTERNAL_LABEL (loc_section_label,
- DEBUG_LOC_SECTION_LABEL, 0);
- ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
- output_location_lists (die);
- }
-
if (debug_info_level >= DINFO_LEVEL_NORMAL)
add_AT_lineptr (comp_unit_die, DW_AT_stmt_list,
debug_line_section_label);
@@ -22481,6 +22559,17 @@ dwarf2out_finish (const char *filename)
switch_to_section (debug_abbrev_section);
output_abbrev_section ();
+ /* Output location list section if necessary. */
+ if (have_location_lists)
+ {
+ /* Output the location lists info. */
+ switch_to_section (debug_loc_section);
+ ASM_GENERATE_INTERNAL_LABEL (loc_section_label,
+ DEBUG_LOC_SECTION_LABEL, 0);
+ ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
+ output_location_lists (die);
+ }
+
/* Output public names table if necessary. */
if (!VEC_empty (pubname_entry, pubname_table))
{