aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-09-17 19:27:00 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2009-09-17 17:27:00 +0000
commite7f373fa6952ad2c1bc8980dc29f584127ee0171 (patch)
treea9d4821ab39040c52fd6eded99a01e7bd28822ec
parentd2da4af2c7872e1d9892cc5b3792d10dd86782a4 (diff)
downloadgcc-e7f373fa6952ad2c1bc8980dc29f584127ee0171.zip
gcc-e7f373fa6952ad2c1bc8980dc29f584127ee0171.tar.gz
gcc-e7f373fa6952ad2c1bc8980dc29f584127ee0171.tar.bz2
dwarf2out.c: Include tree-pass.h and gimple.h.
* dwarf2out.c: Include tree-pass.h and gimple.h. (loc_list_plus_const): New function. (loc_descriptor_from_tree_1): Rename to ... (loc_descriptor_from_tree): ... remove original. (loc_list_from_tree): New function. (add_AT_location_description): Accept location list. (tls_mem_loc_descriptor): Update call of loc_descriptor_from_tree. (concatn_mem_loc_descriptor): Remove. (mem_loc_descriptor): Handle CONCAT/CONCATN and VAR_LOCATION by returning NULL. (secname_for_decl): Move up. (hidden_reference_p): New function; break out from ... (loc_by_refernece): ... here; move up. (dw_loc_list): New function. (single_element_loc_list): New function. (single_element_loc_list_p): New function. (add_loc_descr_to_each): New function. (add_loc_list): New function. (loc_descr_from_tree): Make wraper of loc_list_from_tree. (loc_list_from_tree): Reroganized from loc_descr_from_tree; add diagnostics why expansion failed. (add_location_or_const_value_attribute): Support location lists. (add_bound_info): Likewise. (descr_info_loc): Update call of loc_descriptor_from_tree. (gen_variable_die): Work on location lists. * final.c (pass_final): Add dump file. * Makefile.in (dwarf2out.o): Add new dependencies. From-SVN: r151807
-rw-r--r--gcc/ChangeLog30
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/dwarf2out.c773
-rw-r--r--gcc/final.c2
4 files changed, 567 insertions, 240 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 27276f9..bc01e5e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,33 @@
+2009-09-17 Jan Hubicka <jh@suse.cz>
+
+ * dwarf2out.c: Include tree-pass.h and gimple.h.
+ (loc_list_plus_const): New function.
+ (loc_descriptor_from_tree_1): Rename to ...
+ (loc_descriptor_from_tree): ... remove original.
+ (loc_list_from_tree): New function.
+ (add_AT_location_description): Accept location list.
+ (tls_mem_loc_descriptor): Update call of loc_descriptor_from_tree.
+ (concatn_mem_loc_descriptor): Remove.
+ (mem_loc_descriptor): Handle CONCAT/CONCATN and VAR_LOCATION by
+ returning NULL.
+ (secname_for_decl): Move up.
+ (hidden_reference_p): New function; break out from ...
+ (loc_by_refernece): ... here; move up.
+ (dw_loc_list): New function.
+ (single_element_loc_list): New function.
+ (single_element_loc_list_p): New function.
+ (add_loc_descr_to_each): New function.
+ (add_loc_list): New function.
+ (loc_descr_from_tree): Make wraper of loc_list_from_tree.
+ (loc_list_from_tree): Reroganized from loc_descr_from_tree;
+ add diagnostics why expansion failed.
+ (add_location_or_const_value_attribute): Support location lists.
+ (add_bound_info): Likewise.
+ (descr_info_loc): Update call of loc_descriptor_from_tree.
+ (gen_variable_die): Work on location lists.
+ * final.c (pass_final): Add dump file.
+ * Makefile.in (dwarf2out.o): Add new dependencies.
+
2009-09-17 Janis Johnson <janis187@us.ibm.com>
PR c/41049
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 7c0a235..cbd68d8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2731,7 +2731,7 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
output.h $(DIAGNOSTIC_H) $(REAL_H) hard-reg-set.h $(REGS_H) $(EXPR_H) \
libfuncs.h $(TOPLEV_H) dwarf2out.h reload.h $(GGC_H) $(EXCEPT_H) dwarf2asm.h \
$(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) \
- $(MD5_H) $(INPUT_H) $(FUNCTION_H) $(VARRAY_H)
+ $(MD5_H) $(INPUT_H) $(FUNCTION_H) $(VARRAY_H) $(GIMPLE_H) $(TREE_PASS_H)
dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FLAGS_H) $(RTL_H) $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) \
gt-dwarf2asm.h $(DWARF2_H) $(SPLAY_TREE_H) $(TARGET_H)
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 14836d5..7e43d1b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -89,6 +89,8 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "cgraph.h"
#include "input.h"
+#include "gimple.h"
+#include "tree-pass.h"
#ifdef DWARF2_DEBUGGING_INFO
static void dwarf2out_source_line (unsigned int, const char *, int, bool);
@@ -4655,6 +4657,16 @@ loc_descr_plus_const (dw_loc_descr_ref *list_head, HOST_WIDE_INT offset)
}
}
+/* Add a constant OFFSET to a location list. */
+
+static void
+loc_list_plus_const (dw_loc_list_ref list_head, HOST_WIDE_INT offset)
+{
+ dw_loc_list_ref d;
+ for (d = list_head; d != NULL; d = d->dw_loc_next)
+ loc_descr_plus_const (&d->expr, offset);
+}
+
/* Return the size of a location descriptor. */
static unsigned long
@@ -5938,8 +5950,8 @@ static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx,
enum var_init_status);
static dw_loc_descr_ref loc_descriptor (rtx, enum machine_mode mode,
enum var_init_status);
-static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
-static dw_loc_descr_ref loc_descriptor_from_tree (tree);
+static dw_loc_list_ref loc_list_from_tree (tree, int);
+static dw_loc_descr_ref loc_descriptor_from_tree (tree, int);
static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
static tree field_type (const_tree);
static unsigned int simple_type_align_in_bits (const_tree);
@@ -5947,7 +5959,7 @@ static unsigned int simple_decl_align_in_bits (const_tree);
static unsigned HOST_WIDE_INT simple_type_size_in_bits (const_tree);
static HOST_WIDE_INT field_byte_offset (const_tree);
static void add_AT_location_description (dw_die_ref, enum dwarf_attribute,
- dw_loc_descr_ref);
+ dw_loc_list_ref);
static void add_data_member_location_attribute (dw_die_ref, tree);
static void add_const_value_attribute (dw_die_ref, rtx);
static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
@@ -10958,36 +10970,6 @@ is_based_loc (const_rtx rtl)
&& CONST_INT_P (XEXP (rtl, 1)))));
}
-/* Return a descriptor that describes the concatenation of N locations
- used to form the address of a memory location. */
-
-static dw_loc_descr_ref
-concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode,
- enum var_init_status initialized)
-{
- unsigned int i;
- dw_loc_descr_ref cc_loc_result = NULL;
- unsigned int n = XVECLEN (concatn, 0);
-
- for (i = 0; i < n; ++i)
- {
- dw_loc_descr_ref ref;
- rtx x = XVECEXP (concatn, 0, i);
-
- ref = mem_loc_descriptor (x, mode, VAR_INIT_STATUS_INITIALIZED);
- if (ref == NULL)
- return NULL;
-
- add_loc_descr (&cc_loc_result, ref);
- add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
- }
-
- if (cc_loc_result && initialized == VAR_INIT_STATUS_UNINITIALIZED)
- add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
-
- return cc_loc_result;
-}
-
/* Try to handle TLS MEMs, for which mem_loc_descriptor on XEXP (mem, 0)
failed. */
@@ -11006,7 +10988,7 @@ tls_mem_loc_descriptor (rtx mem)
|| !DECL_THREAD_LOCAL_P (base))
return NULL;
- loc_result = loc_descriptor_from_tree_1 (MEM_EXPR (mem), 2);
+ loc_result = loc_descriptor_from_tree (MEM_EXPR (mem), 2);
if (loc_result == NULL)
return NULL;
@@ -11016,6 +10998,26 @@ tls_mem_loc_descriptor (rtx mem)
return loc_result;
}
+/* Output debug info about reason why we failed to expand expression as dwarf
+ expression. */
+
+static void
+expansion_failed (tree expr, rtx rtl, char const *reason)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Failed to expand as dwarf: ");
+ if (expr)
+ print_generic_expr (dump_file, expr, dump_flags);
+ if (rtl)
+ {
+ fprintf (dump_file, "\n");
+ print_rtl (dump_file, rtl);
+ }
+ fprintf (dump_file, "\nReason: %s\n", reason);
+ }
+}
+
/* The following routine converts the RTL for a variable or parameter
(resident in memory) into an equivalent Dwarf representation of a
mechanism for getting the address of that same variable onto the top of a
@@ -11163,7 +11165,11 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
FIXME: might try to use DW_OP_const_value here, though
DW_OP_piece complicates it. */
if (!marked)
- return 0;
+ {
+ expansion_failed (NULL_TREE, rtl,
+ "Constant was removed from constant pool.\n");
+ return 0;
+ }
}
if (GET_CODE (rtl) == SYMBOL_REF
@@ -11193,6 +11199,14 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
VEC_safe_push (rtx, gc, used_rtx_array, rtl);
break;
+ case CONCAT:
+ case CONCATN:
+ case VAR_LOCATION:
+ expansion_failed (NULL_TREE, rtl,
+ "CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
+ gcc_unreachable ();
+ return 0;
+
case PRE_MODIFY:
/* Extract the PLUS expression nested inside and fall into
PLUS code below. */
@@ -11322,11 +11336,6 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
mem_loc_result = int_loc_descriptor (INTVAL (rtl));
break;
- case CONCATN:
- mem_loc_result = concatn_mem_loc_descriptor (rtl, mode,
- VAR_INIT_STATUS_INITIALIZED);
- break;
-
case EQ:
op = DW_OP_eq;
goto do_scompare;
@@ -11972,16 +11981,310 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
return loc_result;
}
-/* Similar, but generate the descriptor from trees instead of rtl. This comes
- up particularly with variable length arrays. WANT_ADDRESS is 2 if this is
- a top-level invocation of loc_descriptor_from_tree; is 1 if this is not a
- top-level invocation, and we require the address of LOC; is 0 if we require
- the value of LOC. */
+/* We need to figure out what section we should use as the base for the
+ address ranges where a given location is valid.
+ 1. If this particular DECL has a section associated with it, use that.
+ 2. If this function has a section associated with it, use that.
+ 3. Otherwise, use the text section.
+ XXX: If you split a variable across multiple sections, we won't notice. */
+
+static const char *
+secname_for_decl (const_tree decl)
+{
+ const char *secname;
+
+ if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_SECTION_NAME (decl))
+ {
+ tree sectree = DECL_SECTION_NAME (decl);
+ secname = TREE_STRING_POINTER (sectree);
+ }
+ else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
+ {
+ tree sectree = DECL_SECTION_NAME (current_function_decl);
+ secname = TREE_STRING_POINTER (sectree);
+ }
+ else if (cfun && in_cold_section_p)
+ secname = crtl->subsections.cold_section_label;
+ else
+ secname = text_section_label;
+
+ return secname;
+}
+
+/* Return true when DECL_BY_REFERENCE is defined and set for DECL. */
+
+static bool
+decl_by_reference_p (tree decl)
+{
+ return ((TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL
+ || TREE_CODE (decl) == VAR_DECL)
+ && DECL_BY_REFERENCE (decl));
+}
+
+
+/* Dereference a location expression LOC if DECL is passed by invisible
+ reference. */
static dw_loc_descr_ref
-loc_descriptor_from_tree_1 (tree loc, int want_address)
+loc_by_reference (dw_loc_descr_ref loc, tree decl)
+{
+ HOST_WIDE_INT size;
+ enum dwarf_location_atom op;
+
+ if (loc == NULL)
+ return NULL;
+
+ if (!decl_by_reference_p (decl))
+ return loc;
+
+ /* If loc is DW_OP_reg{0...31,x}, don't add DW_OP_deref, instead
+ change it into corresponding DW_OP_breg{0...31,x} 0. Then the
+ location expression is considered to be address of a memory location,
+ rather than the register itself. */
+ if (((loc->dw_loc_opc >= DW_OP_reg0 && loc->dw_loc_opc <= DW_OP_reg31)
+ || loc->dw_loc_opc == DW_OP_regx)
+ && (loc->dw_loc_next == NULL
+ || (loc->dw_loc_next->dw_loc_opc == DW_OP_GNU_uninit
+ && loc->dw_loc_next->dw_loc_next == NULL)))
+ {
+ if (loc->dw_loc_opc == DW_OP_regx)
+ {
+ loc->dw_loc_opc = DW_OP_bregx;
+ loc->dw_loc_oprnd2.v.val_int = 0;
+ }
+ else
+ {
+ loc->dw_loc_opc
+ = (enum dwarf_location_atom)
+ (loc->dw_loc_opc + (DW_OP_breg0 - DW_OP_reg0));
+ loc->dw_loc_oprnd1.v.val_int = 0;
+ }
+ return loc;
+ }
+
+ size = int_size_in_bytes (TREE_TYPE (decl));
+ if (size > DWARF2_ADDR_SIZE || size == -1)
+ return 0;
+ else if (size == DWARF2_ADDR_SIZE)
+ op = DW_OP_deref;
+ else
+ op = DW_OP_deref_size;
+ add_loc_descr (&loc, new_loc_descr (op, size, 0));
+ return loc;
+}
+
+/* Return dwarf representation of location list representing for
+ LOC_LIST of DECL. */
+
+static dw_loc_list_ref
+dw_loc_list (var_loc_list * loc_list, tree decl, bool toplevel)
+{
+ const char *endname, *secname;
+ dw_loc_list_ref list;
+ rtx varloc;
+ enum var_init_status initialized;
+ struct var_loc_node *node;
+ dw_loc_descr_ref descr;
+ char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
+
+ bool by_reference = decl_by_reference_p (decl);
+
+ /* Now that we know what section we are using for a base,
+ actually construct the list of locations.
+ The first location information is what is passed to the
+ function that creates the location list, and the remaining
+ locations just get added on to that list.
+ Note that we only know the start address for a location
+ (IE location changes), so to build the range, we use
+ the range [current location start, next location start].
+ This means we have to special case the last node, and generate
+ a range of [last location start, end of function label]. */
+
+ node = loc_list->first;
+ varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+ secname = secname_for_decl (decl);
+
+ if (NOTE_VAR_LOCATION_LOC (node->var_loc_note))
+ initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+ else
+ initialized = VAR_INIT_STATUS_INITIALIZED;
+
+ if (!toplevel || by_reference)
+ {
+ gcc_assert (GET_CODE (varloc) == VAR_LOCATION);
+ /* Single part. */
+ if (GET_CODE (XEXP (varloc, 1)) != PARALLEL)
+ descr = loc_by_reference (mem_loc_descriptor (XEXP (XEXP (varloc, 1), 0),
+ TYPE_MODE (TREE_TYPE (decl)),
+ initialized),
+ decl);
+ else
+ descr = NULL;
+ }
+ else
+ descr = loc_descriptor (varloc, DECL_MODE (decl), initialized);
+
+ if (!current_function_decl)
+ endname = text_end_label;
+ else
+ {
+ ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
+ current_function_funcdef_no);
+ endname = ggc_strdup (label_id);
+ }
+ list = new_loc_list (descr, node->label, node->next ? node->next->label : endname, secname, 1);
+ node = node->next;
+
+ if (!node)
+ return NULL;
+
+ for (; node->next; node = node->next)
+ if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
+ {
+ /* The variable has a location between NODE->LABEL and
+ NODE->NEXT->LABEL. */
+ enum var_init_status initialized =
+ NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+ varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+ if (!toplevel || by_reference)
+ {
+ gcc_assert (GET_CODE (varloc) == VAR_LOCATION);
+ /* Single part. */
+ if (GET_CODE (XEXP (varloc, 1)) != PARALLEL)
+ descr = mem_loc_descriptor (XEXP (XEXP (varloc, 1), 0),
+ TYPE_MODE (TREE_TYPE (decl)), initialized);
+ else
+ descr = NULL;
+ descr = loc_by_reference (descr, decl);
+ }
+ else
+ descr = loc_descriptor (varloc, DECL_MODE (decl), initialized);
+ add_loc_descr_to_loc_list (&list, descr,
+ node->label, node->next->label, secname);
+ }
+
+ /* If the variable has a location at the last label
+ it keeps its location until the end of function. */
+ if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
+ {
+ enum var_init_status initialized =
+ NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+
+ varloc = NOTE_VAR_LOCATION (node->var_loc_note);
+ if (!toplevel || by_reference)
+ {
+ gcc_assert (GET_CODE (varloc) == VAR_LOCATION);
+ /* Single part. */
+ if (GET_CODE (XEXP (varloc, 1)) != PARALLEL)
+ descr = mem_loc_descriptor (XEXP (XEXP (varloc, 1), 0),
+ TYPE_MODE (TREE_TYPE (decl)), initialized);
+ else
+ descr = NULL;
+ descr = loc_by_reference (descr, decl);
+ }
+ else
+ descr = loc_descriptor (varloc, DECL_MODE (decl), initialized);
+ add_loc_descr_to_loc_list (&list, descr, node->label, endname, secname);
+ }
+ return list;
+}
+
+/* Return single element location list containing loc descr REF. */
+
+static dw_loc_list_ref
+single_element_loc_list (dw_loc_descr_ref ref)
+{
+ return new_loc_list (ref, NULL, NULL, NULL, 0);
+}
+
+/* Return if the loc_list has only single element and thus can be represented
+ as location description. */
+
+static bool
+single_element_loc_list_p (dw_loc_list_ref list)
{
- dw_loc_descr_ref ret, ret1;
+ return (!list->dw_loc_next && !list->begin && !list->end);
+}
+
+/* To each location in list LIST add loc descr REF. */
+
+static void
+add_loc_descr_to_each (dw_loc_list_ref list, dw_loc_descr_ref ref)
+{
+ dw_loc_descr_ref copy;
+ add_loc_descr (&list->expr, ref);
+ list = list->dw_loc_next;
+ while (list)
+ {
+ copy = GGC_CNEW (dw_loc_descr_node);
+ memcpy (copy, ref, sizeof (dw_loc_descr_node));
+ add_loc_descr (&list->expr, copy);
+ while (copy->dw_loc_next)
+ {
+ dw_loc_descr_ref new_copy = GGC_CNEW (dw_loc_descr_node);
+ memcpy (new_copy, copy->dw_loc_next, sizeof (dw_loc_descr_node));
+ copy->dw_loc_next = new_copy;
+ copy = new_copy;
+ }
+ list = list->dw_loc_next;
+ }
+}
+
+/* Given two lists RET and LIST
+ produce location list that is result of adding expression in LIST
+ to expression in RET on each possition in program.
+ Might be destructive on both RET and LIST.
+
+ TODO: We handle only simple cases of RET or LIST having at most one
+ element. General case would inolve sorting the lists in program order
+ and merging them that will need some additional work.
+ Adding that will improve quality of debug info especially for SRA-ed
+ structures. */
+
+static void
+add_loc_list (dw_loc_list_ref *ret, dw_loc_list_ref list)
+{
+ if (!list)
+ return;
+ if (!*ret)
+ {
+ *ret = list;
+ return;
+ }
+ if (!list->dw_loc_next)
+ {
+ add_loc_descr_to_each (*ret, list->expr);
+ return;
+ }
+ if (!(*ret)->dw_loc_next)
+ {
+ add_loc_descr_to_each (list, (*ret)->expr);
+ *ret = list;
+ return;
+ }
+ expansion_failed (NULL_TREE, NULL_RTX,
+ "Don't know how to merge two non-trivial"
+ " location lists.\n");
+ *ret = NULL;
+ return;
+}
+
+/* Generate Dwarf location list representing LOC.
+ If WANT_ADDRESS is false, expression computing LOC will be computed
+ If WANT_ADDRESS is 1, expression computing address of LOC will be returned
+ if WANT_ADDRESS is 2, expression computing address useable in location
+ will be returned (i.e. DW_OP_reg can be used
+ to refer to register values)
+ TODO: Dwarf4 adds types to the stack machine that ought to be used here
+ DW_OP_stack_value will help in cases where we fail to find address of the
+ expression.
+ */
+
+static dw_loc_list_ref
+loc_list_from_tree (tree loc, int want_address)
+{
+ dw_loc_descr_ref ret = NULL, ret1 = NULL;
+ dw_loc_list_ref list_ret = NULL, list_ret1 = NULL;
int have_address = 0;
enum dwarf_location_atom op;
@@ -11992,6 +12295,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
switch (TREE_CODE (loc))
{
case ERROR_MARK:
+ expansion_failed (loc, NULL_RTX, "ERROR_MARK");
return 0;
case PLACEHOLDER_EXPR:
@@ -11999,25 +12303,32 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
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
the names of types. */
+ expansion_failed (loc, NULL_RTX, "PLACEHOLDER_EXPR");
return 0;
case CALL_EXPR:
+ expansion_failed (loc, NULL_RTX, "CALL_EXPR");
+ /* There are no opcodes for these operations. */
return 0;
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
+ expansion_failed (loc, NULL_RTX, "PRE/POST INDCREMENT/DECREMENT");
/* There are no opcodes for these operations. */
return 0;
case ADDR_EXPR:
/* If we already want an address, there's nothing we can do. */
if (want_address)
- return 0;
+ {
+ expansion_failed (loc, NULL_RTX, "need address of ADDR_EXPR");
+ return 0;
+ }
/* Otherwise, process the argument and look for the address. */
- return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 1);
+ return loc_list_from_tree (TREE_OPERAND (loc, 0), 1);
case VAR_DECL:
if (DECL_THREAD_LOCAL_P (loc))
@@ -12030,7 +12341,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
if (targetm.have_tls)
{
/* If this is not defined, we have no way to emit the
- data. */
+ data. */
if (!targetm.asm_out.output_dwarf_dtprel)
return 0;
@@ -12077,17 +12388,24 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
case PARM_DECL:
if (DECL_HAS_VALUE_EXPR_P (loc))
- return loc_descriptor_from_tree_1 (DECL_VALUE_EXPR (loc),
- want_address);
+ return loc_list_from_tree (DECL_VALUE_EXPR (loc),
+ want_address);
/* FALLTHRU */
case RESULT_DECL:
case FUNCTION_DECL:
{
rtx rtl = rtl_for_decl_location (loc);
+ var_loc_list *loc_list = lookup_decl_loc (loc);
- if (rtl == NULL_RTX)
- return 0;
+ if (loc_list && loc_list->first
+ && (list_ret = dw_loc_list (loc_list, loc, want_address == 2)))
+ have_address = 1;
+ else if (rtl == NULL_RTX)
+ {
+ expansion_failed (loc, NULL_RTX, "DECL has no RTL");
+ return 0;
+ }
else if (CONST_INT_P (rtl))
{
HOST_WIDE_INT val = INTVAL (rtl);
@@ -12096,7 +12414,10 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
ret = int_loc_descriptor (val);
}
else if (GET_CODE (rtl) == CONST_STRING)
- return 0;
+ {
+ expansion_failed (loc, NULL_RTX, "CONST_STRING");
+ return 0;
+ }
else if (CONSTANT_P (rtl))
{
ret = new_loc_descr (DW_OP_addr, 0, 0);
@@ -12109,33 +12430,41 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
/* Certain constructs can only be represented at top-level. */
if (want_address == 2)
- return loc_descriptor (rtl, VOIDmode,
- VAR_INIT_STATUS_INITIALIZED);
-
- mode = GET_MODE (rtl);
- if (MEM_P (rtl))
{
- rtl = XEXP (rtl, 0);
+ ret = loc_descriptor (rtl, VOIDmode,
+ VAR_INIT_STATUS_INITIALIZED);
have_address = 1;
}
- ret = mem_loc_descriptor (rtl, mode, VAR_INIT_STATUS_INITIALIZED);
+ else
+ {
+ mode = GET_MODE (rtl);
+ if (MEM_P (rtl))
+ {
+ rtl = XEXP (rtl, 0);
+ have_address = 1;
+ }
+ ret = mem_loc_descriptor (rtl, mode, VAR_INIT_STATUS_INITIALIZED);
+ }
+ if (!ret)
+ expansion_failed (loc, rtl,
+ "failed to produce loc descriptor for rtl");
}
}
break;
case INDIRECT_REF:
- ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
+ list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
have_address = 1;
break;
case COMPOUND_EXPR:
- return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), want_address);
+ return loc_list_from_tree (TREE_OPERAND (loc, 1), want_address);
CASE_CONVERT:
case VIEW_CONVERT_EXPR:
case SAVE_EXPR:
case MODIFY_EXPR:
- return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), want_address);
+ return loc_list_from_tree (TREE_OPERAND (loc, 0), want_address);
case COMPONENT_REF:
case BIT_FIELD_REF:
@@ -12151,26 +12480,35 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
&unsignedp, &volatilep, false);
- if (obj == loc)
- return 0;
+ gcc_assert (obj != loc);
- ret = loc_descriptor_from_tree_1 (obj, 1);
- if (ret == 0
- || bitpos % BITS_PER_UNIT != 0 || bitsize % BITS_PER_UNIT != 0)
+ list_ret = loc_list_from_tree (obj, 1);
+ if (list_ret == 0)
return 0;
+ if (bitpos % BITS_PER_UNIT != 0 || bitsize % BITS_PER_UNIT != 0)
+ {
+ expansion_failed (loc, NULL_RTX,
+ "bitfield access");
+ return 0;
+ }
if (offset != NULL_TREE)
{
/* Variable offset. */
- ret1 = loc_descriptor_from_tree_1 (offset, 0);
- if (ret1 == 0)
+ list_ret1 = loc_list_from_tree (offset, 0);
+ if (list_ret1 == 0)
return 0;
- add_loc_descr (&ret, ret1);
- add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
+ add_loc_list (&list_ret, list_ret1);
+ if (!list_ret)
+ return 0;
+ add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus, 0, 0));
}
bytepos = bitpos / BITS_PER_UNIT;
- loc_descr_plus_const (&ret, bytepos);
+ if (bytepos > 0)
+ add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus_uconst, bytepos, 0));
+ else if (bytepos < 0)
+ loc_list_plus_const (list_ret, bytepos);
have_address = 1;
break;
@@ -12180,7 +12518,11 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
if (host_integerp (loc, 0))
ret = int_loc_descriptor (tree_low_cst (loc, 0));
else
- return 0;
+ {
+ expansion_failed (loc, NULL_RTX,
+ "Integer operand is not host integer");
+ return 0;
+ }
break;
case CONSTRUCTOR:
@@ -12250,11 +12592,11 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST
&& host_integerp (TREE_OPERAND (loc, 1), 0))
{
- ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
- if (ret == 0)
+ list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
+ if (list_ret == 0)
return 0;
- loc_descr_plus_const (&ret, tree_low_cst (TREE_OPERAND (loc, 1), 0));
+ loc_list_plus_const (list_ret, tree_low_cst (TREE_OPERAND (loc, 1), 0));
break;
}
@@ -12298,13 +12640,15 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
goto do_binop;
do_binop:
- ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
- ret1 = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), 0);
- if (ret == 0 || ret1 == 0)
+ list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
+ list_ret1 = loc_list_from_tree (TREE_OPERAND (loc, 1), 0);
+ if (list_ret == 0 || list_ret1 == 0)
return 0;
- add_loc_descr (&ret, ret1);
- add_loc_descr (&ret, new_loc_descr (op, 0, 0));
+ add_loc_list (&list_ret, list_ret1);
+ if (list_ret == 0)
+ return 0;
+ add_loc_descr_to_each (list_ret, new_loc_descr (op, 0, 0));
break;
case TRUTH_NOT_EXPR:
@@ -12321,11 +12665,11 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
goto do_unop;
do_unop:
- ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
- if (ret == 0)
+ list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
+ if (list_ret == 0)
return 0;
- add_loc_descr (&ret, new_loc_descr (op, 0, 0));
+ add_loc_descr_to_each (list_ret, new_loc_descr (op, 0, 0));
break;
case MIN_EXPR:
@@ -12345,29 +12689,29 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
case COND_EXPR:
{
dw_loc_descr_ref lhs
- = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), 0);
- dw_loc_descr_ref rhs
- = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 2), 0);
+ = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
+ dw_loc_list_ref rhs
+ = loc_list_from_tree (TREE_OPERAND (loc, 2), 0);
dw_loc_descr_ref bra_node, jump_node, tmp;
- ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
- if (ret == 0 || lhs == 0 || rhs == 0)
+ list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
+ if (list_ret == 0 || lhs == 0 || rhs == 0)
return 0;
bra_node = new_loc_descr (DW_OP_bra, 0, 0);
- add_loc_descr (&ret, bra_node);
+ add_loc_descr_to_each (list_ret, bra_node);
- add_loc_descr (&ret, rhs);
+ add_loc_list (&list_ret, rhs);
jump_node = new_loc_descr (DW_OP_skip, 0, 0);
- add_loc_descr (&ret, jump_node);
+ add_loc_descr_to_each (list_ret, jump_node);
- add_loc_descr (&ret, lhs);
+ add_loc_descr_to_each (list_ret, lhs);
bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
bra_node->dw_loc_oprnd1.v.val_loc = lhs;
/* ??? Need a node to point the skip at. Use a nop. */
tmp = new_loc_descr (DW_OP_nop, 0, 0);
- add_loc_descr (&ret, tmp);
+ add_loc_descr_to_each (list_ret, tmp);
jump_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
jump_node->dw_loc_oprnd1.v.val_loc = tmp;
}
@@ -12381,7 +12725,11 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
up, for instance, with the C STMT_EXPR. */
if ((unsigned int) TREE_CODE (loc)
>= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
- return 0;
+ {
+ expansion_failed (loc, NULL_RTX,
+ "language specific tree node");
+ return 0;
+ }
#ifdef ENABLE_CHECKING
/* Otherwise this is a generic code; we should just lists all of
@@ -12394,32 +12742,60 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
#endif
}
+ if (!ret && !list_ret)
+ return 0;
+
/* Show if we can't fill the request for an address. */
if (want_address && !have_address)
- return 0;
+ {
+ expansion_failed (loc, NULL_RTX,
+ "Want address and only have value");
+ return 0;
+ }
+
+ gcc_assert (!ret || !list_ret);
/* If we've got an address and don't want one, dereference. */
- if (!want_address && have_address && ret)
+ if (!want_address && have_address)
{
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
if (size > DWARF2_ADDR_SIZE || size == -1)
- return 0;
+ {
+ expansion_failed (loc, NULL_RTX,
+ "DWARF address size mismatch");
+ return 0;
+ }
else if (size == DWARF2_ADDR_SIZE)
op = DW_OP_deref;
else
op = DW_OP_deref_size;
- add_loc_descr (&ret, new_loc_descr (op, size, 0));
+ if (ret)
+ add_loc_descr (&ret, new_loc_descr (op, size, 0));
+ else
+ add_loc_descr_to_each (list_ret, new_loc_descr (op, size, 0));
}
+ if (ret)
+ list_ret = single_element_loc_list (ret);
- return ret;
+ return list_ret;
}
-static inline dw_loc_descr_ref
-loc_descriptor_from_tree (tree loc)
+/* Same as above but return only single location expression. */
+static dw_loc_descr_ref
+loc_descriptor_from_tree (tree loc, int want_address)
{
- return loc_descriptor_from_tree_1 (loc, 2);
+ dw_loc_list_ref ret = loc_list_from_tree (loc, want_address);
+ if (!ret)
+ return NULL;
+ if (ret->dw_loc_next)
+ {
+ expansion_failed (loc, NULL_RTX,
+ "Location list where only loc descriptor needed");
+ return NULL;
+ }
+ return ret->expr;
}
/* Given a value, round it up to the lowest multiple of `boundary'
@@ -12529,9 +12905,9 @@ field_byte_offset (const_tree decl)
field_size_tree = DECL_SIZE (decl);
/* The size could be unspecified if there was an error, or for
- a flexible array member. */
+ a flexible array member. */
if (!field_size_tree)
- field_size_tree = bitsize_zero_node;
+ field_size_tree = bitsize_zero_node;
/* If the size of the field is not constant, use the type size. */
if (host_integerp (field_size_tree, 1))
@@ -12626,10 +13002,14 @@ field_byte_offset (const_tree decl)
static inline void
add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind,
- dw_loc_descr_ref descr)
+ dw_loc_list_ref descr)
{
- if (descr != 0)
- add_AT_loc (die, attr_kind, descr);
+ if (descr == 0)
+ return;
+ if (single_element_loc_list_p (descr))
+ add_AT_loc (die, attr_kind, descr->expr);
+ else
+ add_AT_loc_list (die, attr_kind, descr);
}
/* Attach the specialized form of location attribute used for data members of
@@ -13267,36 +13647,6 @@ rtl_for_decl_location (tree decl)
return rtl;
}
-/* We need to figure out what section we should use as the base for the
- address ranges where a given location is valid.
- 1. If this particular DECL has a section associated with it, use that.
- 2. If this function has a section associated with it, use that.
- 3. Otherwise, use the text section.
- XXX: If you split a variable across multiple sections, we won't notice. */
-
-static const char *
-secname_for_decl (const_tree decl)
-{
- const char *secname;
-
- if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_SECTION_NAME (decl))
- {
- tree sectree = DECL_SECTION_NAME (decl);
- secname = TREE_STRING_POINTER (sectree);
- }
- else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
- {
- tree sectree = DECL_SECTION_NAME (current_function_decl);
- secname = TREE_STRING_POINTER (sectree);
- }
- else if (cfun && in_cold_section_p)
- secname = crtl->subsections.cold_section_label;
- else
- secname = text_section_label;
-
- return secname;
-}
-
/* Check whether decl is a Fortran COMMON symbol. If not, NULL_TREE is
returned. If so, the decl for the COMMON block is returned, and the
value is the offset into the common block for the symbol. */
@@ -13347,60 +13697,6 @@ fortran_common (tree decl, HOST_WIDE_INT *value)
return cvar;
}
-/* Dereference a location expression LOC if DECL is passed by invisible
- reference. */
-
-static dw_loc_descr_ref
-loc_by_reference (dw_loc_descr_ref loc, tree decl)
-{
- HOST_WIDE_INT size;
- enum dwarf_location_atom op;
-
- if (loc == NULL)
- return NULL;
-
- if ((TREE_CODE (decl) != PARM_DECL
- && TREE_CODE (decl) != RESULT_DECL
- && TREE_CODE (decl) != VAR_DECL)
- || !DECL_BY_REFERENCE (decl))
- return loc;
-
- /* If loc is DW_OP_reg{0...31,x}, don't add DW_OP_deref, instead
- change it into corresponding DW_OP_breg{0...31,x} 0. Then the
- location expression is considered to be address of a memory location,
- rather than the register itself. */
- if (((loc->dw_loc_opc >= DW_OP_reg0 && loc->dw_loc_opc <= DW_OP_reg31)
- || loc->dw_loc_opc == DW_OP_regx)
- && (loc->dw_loc_next == NULL
- || (loc->dw_loc_next->dw_loc_opc == DW_OP_GNU_uninit
- && loc->dw_loc_next->dw_loc_next == NULL)))
- {
- if (loc->dw_loc_opc == DW_OP_regx)
- {
- loc->dw_loc_opc = DW_OP_bregx;
- loc->dw_loc_oprnd2.v.val_int = 0;
- }
- else
- {
- loc->dw_loc_opc
- = (enum dwarf_location_atom)
- (loc->dw_loc_opc + (DW_OP_breg0 - DW_OP_reg0));
- loc->dw_loc_oprnd1.v.val_int = 0;
- }
- return loc;
- }
-
- size = int_size_in_bytes (TREE_TYPE (decl));
- if (size > DWARF2_ADDR_SIZE || size == -1)
- return 0;
- else if (size == DWARF2_ADDR_SIZE)
- op = DW_OP_deref;
- else
- op = DW_OP_deref_size;
- add_loc_descr (&loc, new_loc_descr (op, size, 0));
- return loc;
-}
-
/* 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
DW_AT_const_value attribute only in those cases where the given variable
@@ -13418,6 +13714,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
{
rtx rtl;
dw_loc_descr_ref descr;
+ dw_loc_list_ref descr_list;
var_loc_list *loc_list;
struct var_loc_node *node;
if (TREE_CODE (decl) == ERROR_MARK)
@@ -13539,18 +13836,18 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
if (descr)
{
descr = loc_by_reference (descr, decl);
- add_AT_location_description (die, attr, descr);
+ add_AT_location_description (die, attr, single_element_loc_list (descr));
return;
}
}
/* We couldn't get any rtl, so try directly generating the location
description from the tree. */
- descr = loc_descriptor_from_tree (decl);
- if (descr)
+ descr_list = loc_list_from_tree (decl, 2);
+ if (descr_list)
{
descr = loc_by_reference (descr, decl);
- add_AT_location_description (die, attr, descr);
+ add_AT_location_description (die, attr, descr_list);
return;
}
/* None of that worked, so it must not really have a location;
@@ -13967,7 +14264,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
case RESULT_DECL:
{
dw_die_ref decl_die = lookup_decl_die (bound);
- dw_loc_descr_ref loc;
+ dw_loc_list_ref loc;
/* ??? Can this happen, or should the variable have been bound
first? Probably it can, since I imagine that we try to create
@@ -13978,7 +14275,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
add_AT_die_ref (subrange_die, bound_attr, decl_die);
else
{
- loc = loc_descriptor_from_tree_1 (bound, 0);
+ loc = loc_list_from_tree (bound, 0);
add_AT_location_description (subrange_die, bound_attr, loc);
}
break;
@@ -13990,10 +14287,10 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
evaluate the value of the array bound. */
dw_die_ref ctx, decl_die;
- dw_loc_descr_ref loc;
+ dw_loc_list_ref list;
- loc = loc_descriptor_from_tree (bound);
- if (loc == NULL)
+ list = loc_list_from_tree (bound, 2);
+ if (list == NULL)
break;
if (current_function_decl == 0)
@@ -14004,7 +14301,10 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
decl_die = new_die (DW_TAG_variable, ctx, bound);
add_AT_flag (decl_die, DW_AT_artificial, 1);
add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
- add_AT_loc (decl_die, DW_AT_location, loc);
+ if (list->dw_loc_next)
+ add_AT_loc_list (decl_die, DW_AT_location, list);
+ else
+ add_AT_loc (decl_die, DW_AT_location, list->expr);
add_AT_die_ref (subrange_die, bound_attr, decl_die);
break;
@@ -14610,12 +14910,12 @@ gen_array_type_die (tree type, dw_die_ref context_die)
&& DECL_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
{
tree szdecl = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
- dw_loc_descr_ref loc = loc_descriptor_from_tree (szdecl);
+ dw_loc_list_ref loc = loc_list_from_tree (szdecl, 2);
size = int_size_in_bytes (TREE_TYPE (szdecl));
if (loc && size > 0)
{
- add_AT_loc (array_die, DW_AT_string_length, loc);
+ add_AT_location_description (array_die, DW_AT_string_length, loc);
if (size != DWARF2_ADDR_SIZE)
add_AT_unsigned (array_die, DW_AT_byte_size, size);
}
@@ -14709,7 +15009,7 @@ descr_info_loc (tree val, tree base_decl)
CASE_CONVERT:
return descr_info_loc (TREE_OPERAND (val, 0), base_decl);
case VAR_DECL:
- return loc_descriptor_from_tree_1 (val, 0);
+ return loc_descriptor_from_tree (val, 0);
case INTEGER_CST:
if (host_integerp (val, 0))
return int_loc_descriptor (tree_low_cst (val, 0));
@@ -15015,7 +15315,7 @@ gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
{
tree type = TREE_TYPE (node);
add_name_and_src_coords_attributes (parm_die, node);
- if (DECL_BY_REFERENCE (node))
+ if (decl_by_reference_p (node))
add_type_attribute (parm_die, TREE_TYPE (type), 0, 0,
context_die);
else
@@ -15467,7 +15767,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
if (cfun->static_chain_decl)
add_AT_location_description (subr_die, DW_AT_static_link,
- loc_descriptor_from_tree (cfun->static_chain_decl));
+ loc_list_from_tree (cfun->static_chain_decl, 2));
}
/* Generate child dies for template paramaters. */
@@ -15637,7 +15937,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
{
tree field;
dw_die_ref com_die;
- dw_loc_descr_ref loc;
+ dw_loc_list_ref loc;
die_node com_die_arg;
var_die = lookup_decl_die (decl_or_origin);
@@ -15645,22 +15945,23 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
{
if (get_AT (var_die, DW_AT_location) == NULL)
{
- loc = loc_descriptor_from_tree (com_decl);
+ loc = loc_list_from_tree (com_decl, off ? 1 : 2);
if (loc)
{
if (off)
{
/* Optimize the common case. */
- if (loc->dw_loc_opc == DW_OP_addr
- && loc->dw_loc_next == NULL
- && GET_CODE (loc->dw_loc_oprnd1.v.val_addr)
+ if (single_element_loc_list_p (loc)
+ && loc->expr->dw_loc_opc == DW_OP_addr
+ && loc->expr->dw_loc_next == NULL
+ && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr)
== SYMBOL_REF)
- loc->dw_loc_oprnd1.v.val_addr
- = plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
+ loc->expr->dw_loc_oprnd1.v.val_addr
+ = plus_constant (loc->expr->dw_loc_oprnd1.v.val_addr, off);
else
- loc_descr_plus_const (&loc, off);
+ loc_list_plus_const (loc, off);
}
- add_AT_loc (var_die, DW_AT_location, loc);
+ add_AT_location_description (var_die, DW_AT_location, loc);
remove_AT (var_die, DW_AT_declaration);
}
}
@@ -15676,7 +15977,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
com_die_arg.decl_id = DECL_UID (com_decl);
com_die_arg.die_parent = context_die;
com_die = (dw_die_ref) htab_find (common_block_die_table, &com_die_arg);
- loc = loc_descriptor_from_tree (com_decl);
+ loc = loc_list_from_tree (com_decl, 2);
if (com_die == NULL)
{
const char *cnam
@@ -15687,10 +15988,10 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
add_name_and_src_coords_attributes (com_die, com_decl);
if (loc)
{
- add_AT_loc (com_die, DW_AT_location, loc);
+ add_AT_location_description (com_die, DW_AT_location, loc);
/* Avoid sharing the same loc descriptor between
DW_TAG_common_block and DW_TAG_variable. */
- loc = loc_descriptor_from_tree (com_decl);
+ loc = loc_list_from_tree (com_decl, 2);
}
else if (DECL_EXTERNAL (decl))
add_AT_flag (com_die, DW_AT_declaration, 1);
@@ -15701,8 +16002,8 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
}
else if (get_AT (com_die, DW_AT_location) == NULL && loc)
{
- add_AT_loc (com_die, DW_AT_location, loc);
- loc = loc_descriptor_from_tree (com_decl);
+ add_AT_location_description (com_die, DW_AT_location, loc);
+ loc = loc_list_from_tree (com_decl, 2);
remove_AT (com_die, DW_AT_declaration);
}
var_die = new_die (DW_TAG_variable, com_die, decl);
@@ -15715,15 +16016,16 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
if (off)
{
/* Optimize the common case. */
- if (loc->dw_loc_opc == DW_OP_addr
- && loc->dw_loc_next == NULL
- && GET_CODE (loc->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF)
- loc->dw_loc_oprnd1.v.val_addr
- = plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
+ if (single_element_loc_list_p (loc)
+ && loc->expr->dw_loc_opc == DW_OP_addr
+ && loc->expr->dw_loc_next == NULL
+ && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF)
+ loc->expr->dw_loc_oprnd1.v.val_addr
+ = plus_constant (loc->expr->dw_loc_oprnd1.v.val_addr, off);
else
- loc_descr_plus_const (&loc, off);
+ loc_list_plus_const (loc, off);
}
- add_AT_loc (var_die, DW_AT_location, loc);
+ add_AT_location_description (var_die, DW_AT_location, loc);
}
else if (DECL_EXTERNAL (decl))
add_AT_flag (var_die, DW_AT_declaration, 1);
@@ -15786,10 +16088,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
tree type = TREE_TYPE (decl);
add_name_and_src_coords_attributes (var_die, decl);
- if ((TREE_CODE (decl) == PARM_DECL
- || TREE_CODE (decl) == RESULT_DECL
- || TREE_CODE (decl) == VAR_DECL)
- && DECL_BY_REFERENCE (decl))
+ if (decl_by_reference_p (decl))
add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
else
add_type_attribute (var_die, type, TREE_READONLY (decl),
@@ -17066,9 +17365,7 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
/* Output any DIEs that are needed to specify the type of this data
object. */
- if ((TREE_CODE (decl_or_origin) == RESULT_DECL
- || TREE_CODE (decl_or_origin) == VAR_DECL)
- && DECL_BY_REFERENCE (decl_or_origin))
+ if (decl_by_reference_p (decl_or_origin))
gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
else
gen_type_die (TREE_TYPE (decl_or_origin), context_die);
diff --git a/gcc/final.c b/gcc/final.c
index 3ecb415..cd36860 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4304,7 +4304,7 @@ struct rtl_opt_pass pass_final =
{
{
RTL_PASS,
- NULL, /* name */
+ "final", /* name */
NULL, /* gate */
rest_of_handle_final, /* execute */
NULL, /* sub */