to ensure that.
@@ -19941,7 +19991,8 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
/* If this is an array type with hidden descriptor, handle it first. */
if (!TREE_ASM_WRITTEN (type)
&& lang_hooks.types.get_array_descr_info
- && lang_hooks.types.get_array_descr_info (type, &info)
+ && lang_hooks.types.get_array_descr_info (type,
+ init_array_descr_info (&info))
This patch sounds very wrong. DW_OP_push_object_address is not in DWARF2
you can really output correctly for DWARF2. It isn't the default on sane
#include "real.h"
#include "function.h" /* For pass_by_reference. */
+#include "dwarf2out.h"
#include "ada.h"
#include "adadecode.h"
@@ -626,6 +627,64 @@ gnat_type_max_size (const_tree gnu_type)
return max_unitsize;
}
+/* Provide information in INFO for debug output about the TYPE array type.
+ Return whether TYPE is handled. */
+
+static bool
+gnat_get_array_descr_info (const_tree type, struct array_descr_info *info)
+{
+ bool convention_fortran_p;
+ tree index_type;
+
+ const_tree dimen, last_dimen;
+ int i;
+
+ if (TREE_CODE (type) != ARRAY_TYPE
+ || !TYPE_DOMAIN (type)
+ || !TYPE_INDEX_TYPE (TYPE_DOMAIN (type)))
+ return false;
+
+ /* Count how many dimentions this array has. */
+ for (i = 0, dimen = type; ; ++i, dimen = TREE_TYPE (dimen))
+ if (i > 0
+ && (TREE_CODE (dimen) != ARRAY_TYPE
+ || !TYPE_MULTI_ARRAY_P (dimen)))
+ break;
+ info->ndimensions = i;
+ convention_fortran_p = TYPE_CONVENTION_FORTRAN_P (type);
+
+ /* TODO??? For row major ordering, we probably want to emit nothing and
+ instead specify it as the default in Dw_TAG_compile_unit. */
+ info->ordering = (convention_fortran_p
+ ? array_descr_ordering_column_major
+ : array_descr_ordering_row_major);
+ info->base_decl = NULL_TREE;
+ info->data_location = NULL_TREE;
+ info->allocated = NULL_TREE;
+ info->associated = NULL_TREE;
+
+ for (i = (convention_fortran_p ? info->ndimensions - 1 : 0),
+ dimen = type;
+
+ 0 <= i && i < info->ndimensions;
+
+ i += (convention_fortran_p ? -1 : 1),
+ dimen = TREE_TYPE (dimen))
+ {
+ /* We are interested in the stored bounds for the debug info. */
+ index_type = TYPE_INDEX_TYPE (TYPE_DOMAIN (dimen));
+
+ info->dimen[i].bounds_type = index_type;
+ info->dimen[i].lower_bound = TYPE_MIN_VALUE (index_type);
+ info->dimen[i].upper_bound = TYPE_MAX_VALUE (index_type);
+ last_dimen = dimen;
+ }
+
+ info->element_type = TREE_TYPE (last_dimen);
+
+ return true;
+}
+
/* GNU_TYPE is a subtype of an integral type. Set LOWVAL to the low bound
and HIGHVAL to the high bound, respectively. */
@@ -916,6 +975,8 @@ gnat_init_ts (void)
#define LANG_HOOKS_TYPE_FOR_SIZE gnat_type_for_size
#undef LANG_HOOKS_TYPES_COMPATIBLE_P
#define LANG_HOOKS_TYPES_COMPATIBLE_P gnat_types_compatible_p
+#undef LANG_HOOKS_GET_ARRAY_DESCR_INFO
+#define LANG_HOOKS_GET_ARRAY_DESCR_INFO gnat_get_array_descr_info
#undef LANG_HOOKS_GET_SUBRANGE_BOUNDS
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS gnat_get_subrange_bounds
#undef LANG_HOOKS_DESCRIPTIVE_TYPE
--
2.1.0
From 166fcbad8529818e492c57b7b9091799bf3ae72d Mon Sep 17 00:00:00 2001
Date: Wed, 3 Sep 2014 09:46:29 +0200
Subject: [PATCH 4/5] Add a few debug utilities for DWARF expressions
* dwarf2out.c (print_loc_descr): New.
(print_dw_val): New.
(print_attribute): New.
(print_loc_descr): New.
(print_die): Use print_dw_val.
(debug_dwarf_loc_descr): New.
* dwarf2out.h (debug_dwarf_loc_descr): New declaration.
---
gcc/dwarf2out.c | 277 +++++++++++++++++++++++++++++++++++---------------------
gcc/dwarf2out.h | 1 +
2 files changed, 176 insertions(+), 102 deletions(-)
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 78a470f..1638da4 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5337,6 +5337,172 @@ print_signature (FILE *outfile, char *sig)
fprintf (outfile, "%02x", sig[i] & 0xff);
}
+static void print_loc_descr (dw_loc_descr_ref, FILE *);
+
+/* Print the value associated to the VAL DWARF value node to OUTFILE. If
+ RECURSE, output location descriptor operations. */
+
+static void
+print_dw_val (dw_val_node *val, bool recurse, FILE *outfile)
+{
+ switch (val->val_class)
+ {
+ fprintf (outfile, "address");
+ break;
+ fprintf (outfile, "offset");
+ break;
+ fprintf (outfile, "location descriptor");
+ if (val->v.val_loc == NULL)
+ fprintf (outfile, " -> <null>\n");
+ else if (recurse)
+ {
+ fprintf (outfile, ":\n");
+ print_indent += 4;
+ print_loc_descr (val->v.val_loc, outfile);
+ print_indent -= 4;
+ }
+ else
+ fprintf (outfile, " (%p)\n", (void *) val->v.val_loc);
+ break;
+ fprintf (outfile, "location list -> label:%s",
+ val->v.val_loc_list->ll_symbol);
+ break;
+ fprintf (outfile, "range list");
+ break;
+ fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, val->v.val_int);
+ break;
+ fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, val->v.val_unsigned);
+ break;
+ fprintf (outfile, "constant ("HOST_WIDE_INT_PRINT_DEC","\
+ HOST_WIDE_INT_PRINT_UNSIGNED")",
+ val->v.val_double.high,
+ val->v.val_double.low);
+ break;
+ {
+ int i = val->v.val_wide->get_len ();
+ fprintf (outfile, "constant (");
+ gcc_assert (i > 0);
+ if (val->v.val_wide->elt (i - 1) == 0)
+ fprintf (outfile, "0x");
+ fprintf (outfile, HOST_WIDE_INT_PRINT_HEX,
+ val->v.val_wide->elt (--i));
+ while (--i >= 0)
+ fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX,
+ val->v.val_wide->elt (i));
+ fprintf (outfile, ")");
+ break;
+ }
+ fprintf (outfile, "floating-point or vector constant");
+ break;
+ fprintf (outfile, "%u", val->v.val_flag);
+ break;
+ if (val->v.val_die_ref.die != NULL)
+ {
+ dw_die_ref die = val->v.val_die_ref.die;
+
+ if (die->comdat_type_p)
+ {
+ fprintf (outfile, "die -> signature: ");
+ print_signature (outfile,
+ die->die_id.die_type_node->signature);
+ }
+ else if (die->die_id.die_symbol)
+ fprintf (outfile, "die -> label: %s", die->die_id.die_symbol);
+ else
+ fprintf (outfile, "die -> %ld", die->die_offset);
+ fprintf (outfile, " (%p)", (void *) die);
+ }
+ else
+ fprintf (outfile, "die -> <null>");
+ break;
+ val->v.val_vms_delta.lbl2, val->v.val_vms_delta.lbl1);
+ break;
+ fprintf (outfile, "label: %s", val->v.val_lbl_id);
+ break;
+ if (val->v.val_str->str != NULL)
+ fprintf (outfile, "\"%s\"", val->v.val_str->str);
+ else
+ fprintf (outfile, "<null>");
+ break;
+ fprintf (outfile, "\"%s\" (%d)", val->v.val_file->filename,
+ val->v.val_file->emitted_number);
+ break;
+ {
+ int i;
+
+ for (i = 0; i < 8; i++)
+ fprintf (outfile, "%02x", val->v.val_data8[i]);
+ break;
+ }
+ break;
+ }
+}
+
+/* Likewise, for a DIE attribute. */
+
+static void
+print_attribute (dw_attr_ref a, bool recurse, FILE *outfile)
+{
+ print_dw_val (&a->dw_attr_val, recurse, outfile);
+}
+
+/* Print the list of operands in the LOC location description to OUTFILE. This
+ routine is a debugging aid only. */
+
+static void
+print_loc_descr (dw_loc_descr_ref loc, FILE *outfile)
+{
+ dw_loc_descr_ref l = loc;
+
+ if (loc == NULL)
+ {
+ print_spaces (outfile);
+ fprintf (outfile, "<null>\n");
+ return;
+ }
+
+ for (l = loc; l != NULL; l = l->dw_loc_next)
+ {
+ print_spaces (outfile);
+ fprintf (outfile, "(%p) %s",
+ (void *) l,
+ dwarf_stack_op_name (l->dw_loc_opc));
+ if (l->dw_loc_oprnd1.val_class != dw_val_class_none)
+ {
+ fprintf (outfile, " ");
+ print_dw_val (&l->dw_loc_oprnd1, false, outfile);
+ }
+ if (l->dw_loc_oprnd2.val_class != dw_val_class_none)
+ {
+ fprintf (outfile, ", ");
+ print_dw_val (&l->dw_loc_oprnd2, false, outfile);
+ }
+ fprintf (outfile, "\n");
+ }
+}
+
/* Print the information associated with a given DIE, and its children.
This routine is a debugging aid only. */
@@ -5369,108 +5535,7 @@ print_die (dw_die_ref die, FILE *outfile)
print_spaces (outfile);
fprintf (outfile, " %s: ", dwarf_attr_name (a->dw_attr));
- switch (AT_class (a))
- {
- fprintf (outfile, "address");
- break;
- fprintf (outfile, "offset");
- break;
- fprintf (outfile, "location descriptor");
- break;
- fprintf (outfile, "location list -> label:%s",
- AT_loc_list (a)->ll_symbol);
- break;
- fprintf (outfile, "range list");
- break;
- fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, AT_int (a));
- break;
- fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a));
- break;
- fprintf (outfile, "constant ("HOST_WIDE_INT_PRINT_DEC","\
- HOST_WIDE_INT_PRINT_UNSIGNED")",
- a->dw_attr_val.v.val_double.high,
- a->dw_attr_val.v.val_double.low);
- break;
- {
- int i = a->dw_attr_val.v.val_wide->get_len ();
- fprintf (outfile, "constant (");
- gcc_assert (i > 0);
- if (a->dw_attr_val.v.val_wide->elt (i - 1) == 0)
- fprintf (outfile, "0x");
- fprintf (outfile, HOST_WIDE_INT_PRINT_HEX,
- a->dw_attr_val.v.val_wide->elt (--i));
- while (--i >= 0)
- fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX,
- a->dw_attr_val.v.val_wide->elt (i));
- fprintf (outfile, ")");
- break;
- }
- fprintf (outfile, "floating-point or vector constant");
- break;
- fprintf (outfile, "%u", AT_flag (a));
- break;
- if (AT_ref (a) != NULL)
- {
- if (AT_ref (a)->comdat_type_p)
- {
- fprintf (outfile, "die -> signature: ");
- print_signature (outfile,
- AT_ref (a)->die_id.die_type_node->signature);
- }
- else if (AT_ref (a)->die_id.die_symbol)
- fprintf (outfile, "die -> label: %s",
- AT_ref (a)->die_id.die_symbol);
- else
- fprintf (outfile, "die -> %ld", AT_ref (a)->die_offset);
- fprintf (outfile, " (%p)", (void *) AT_ref (a));
- }
- else
- fprintf (outfile, "die -> <null>");
- break;
- AT_vms_delta2 (a), AT_vms_delta1 (a));
- break;
- fprintf (outfile, "label: %s", AT_lbl (a));
- break;
- if (AT_string (a) != NULL)
- fprintf (outfile, "\"%s\"", AT_string (a));
- else
- fprintf (outfile, "<null>");
- break;
- fprintf (outfile, "\"%s\" (%d)", AT_file (a)->filename,
- AT_file (a)->emitted_number);
- break;
- {
- int i;
-
- for (i = 0; i < 8; i++)
- fprintf (outfile, "%02x", a->dw_attr_val.v.val_data8[i]);
- break;
- }
- break;
- }
-
+ print_attribute (a, true, outfile);
fprintf (outfile, "\n");
}
@@ -5484,6 +5549,14 @@ print_die (dw_die_ref die, FILE *outfile)
fprintf (outfile, "\n");
}
+/* Print the list of operations in the LOC location description. */
+
+DEBUG_FUNCTION void
+debug_dwarf_loc_descr (dw_loc_descr_ref loc)
+{
+ print_loc_descr (loc, stderr);
+}
+
/* Print the information collected for a given DIE. */
DEBUG_FUNCTION void
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 8b03e78..fbcb70a 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -254,6 +254,7 @@ extern void dwarf2out_emit_cfi (dw_cfi_ref cfi);
extern void debug_dwarf (void);
struct die_struct;
extern void debug_dwarf_die (struct die_struct *);
+extern void debug_dwarf_loc_descr (dw_loc_descr_ref);
extern void debug (die_struct &ref);
extern void debug (die_struct *ptr);
extern void dwarf2out_set_demangle_name_func (const char *(*) (const char *));
--
2.1.0
From e029b9300c58a0ffbfa1b7f81381a937a60b27fd Mon Sep 17 00:00:00 2001
Date: Wed, 3 Sep 2014 09:46:32 +0200
Subject: [PATCH 5/5] dwarf2out.c: do not short-circuit add_bound_info in array
lang-hook
gcc/
* dwarf2out.h (struct array_descr_info): Remove the base_decl field.
* dwarf2out.c (init_array_descr_info): Update accordingly.
(enum dw_scalar_form): New.
(add_scalar_info): New.
(loc_list_from_tree): Handle PLACEHOLDER_EXPR nodes for
type-related expressions.
(add_bound_info): Use add_scalar_info.
(descr_info_loc): Remove.
(add_descr_info_field): Remove.
(gen_descr_array_type_die): Switch add_descr_info_field calls
into add_scalar_info/add_bound_info ones.
gcc/ada/
* gcc-interface/misc.c (gnat_get_array_descr_info): Remove base_decl
initialization.
gcc/fortran/
* trans-types.c (gfc_get_array_descr_info): Use PLACEHOLDER_EXPR nodes
instead of VAR_DECL ones in type-related expressions. Remove base_decl
initialization.
Ugh, I must say I don't like PLACEHOLDER_EXPRs at all.