Re: [RFA] print arrays with indexes

Joel Brobecker
2005-10-03T06:17:40Z

[-- Attachment #1: Type: text/plain, Size: 4276 bytes --]

> > + if (TYPE_CODE (index) == TYPE_CODE_RANGE)
> > + index = TYPE_TARGET_TYPE (index);
> >
> > which the function used to have. I couldn't understand why this
> > was necessary, and a look at where the type was used showed that
> > this was not necessary, as ada_print_scalar, the only eventual consumer
> > of that type, knew how to handle range types. I would think the same is
> > true of all other languages, right?
>
> Not sure what you mean by "used to have", to be honest. I guess this
> code had some prior life in an ACT tree, if you didn't write it? It
> seems like the sort of check that only Ada would need.

I wasn't clear, sorry. The code in get_array_low_bound() has been
extracted from ada-valprint.c:print_optional_low_bound(). That's where
all the extra code comes from.

> And, this code is still in the patch below. It's definitely dead code,
> though, so I assume you meant to remove it.

Yes. I removed it in one tree, which I tested with our full Ada
testsuite, and forgot to remove it from the tree I'm using to submit
this change. Good catch. Updated patch attached, with the testsuite
rerun one more time, no regression.

> Should the "return 0;" cases in get_array_low_bound be errors? Or even
> internal errors (probably not)?

I don't think we should use an internal error in this case, since the
erroneous situation can also come from incorrect debugging information.
In this case, it would be misleading to label this as an internal error
when the problem is outside the debugger.

I wouldn't use an error in this case either, as it allows us to emit
a warning instead, and recover in a way that at least allows us to
print the array. Otherwise, it's more complicated to still print the
array.

So I would leave this unchanged. Or perhaps a little comment addition
before the function, along with the description, explaining the above?

> There's already lots of code that uses TYPE_LOW_BOUND (TYPE_INDEX_TYPE
> (array_type)). If that's not valid, we need to know why not.

The new function does essentially this, except that it adds a bit
of double-checking, probably to avoid falling in a trap laid by
incorrect debugging information.

I'm including the ChangeLog again, as reviewing it, I noticed that
I forgot to include scm-lang.c.

2005-10-02 Joel Brobecker <brobecker@adacore.com>

* language.h (language_defn): New field la_print_array_index.
(LA_PRINT_ARRAY_INDEX): New macro.
(default_print_array_index): Add declaration.
* language.c (default_print_array_index): new function.
(unknown_language): Add value for new field.
(auto_language): Likewise.
(local_language): Likewise.
* ada-lang.c (ada_print_array_index): New function.
(ada_language_defn): Add value for new field.
* c-lang.c (c_language_defn): Likewise.
(cpluc_language_defn): Likewise.
(asm_language_defn): Likewise.
(minimal_language_defn): Likewise.
* f-lang.c (f_language_defn): Likewise.
* jv-lang.c (java_language_defn): Likewise.
* m2-lang.c (m2_language_defn): Likewise.
* objc-lang.c (objc_language_defn): Likewise.
* p-lang.c (pascal_language_defn): Likewise.
* scm-lang.c (scm_language_defn): Likewise.
* valprint.h (print_array_indexes_p): Add declaration.
(get_array_low_bound): Add declaration.
(maybe_print_array_index): Add declaration.
* valprint.c (print_array_indexes): New static variable.
(show_print_array_indexes): New function.
(print_array_indexes_p): New function.
(get_array_low_bound): New function.
(maybe_print_array_index): New function.
(val_print_array_elements): Print the index of each element if
requested by the user.
(_initialize_valprint): Add new array-indexes "set/show print" command.
* ada-valprint.c (print_optional_low_bound): Replace extracted code
by call to ada_get_array_low_bound_and_type(). Stop printing the low
bound if indexes will be printed for all elements of the array.
(val_print_packed_array_elements): Print the index of each element
of the array if necessary.

Re-tested on x86-linux, no regression.

Thanks,
--
Joel

[-- Attachment #2: idx.diff --]
[-- Type: text/plain, Size: 15671 bytes --]

Index: language.h
===================================================================
RCS file: /cvs/src/src/gdb/language.h,v
retrieving revision 1.35
diff -u -p -r1.35 language.h
--- language.h 9 May 2005 21:20:34 -0000 1.35
+++ language.h 3 Oct 2005 06:13:28 -0000
@@ -275,6 +275,12 @@ struct language_defn
void (*la_language_arch_info) (struct gdbarch *,
struct language_arch_info *);

+ /* Print the index of an element of an array. */
+ void (*la_print_array_index) (struct value *index_value,
+ struct ui_file *stream,
+ int format,
+ enum val_prettyprint pretty);
+
/* Add fields above this point, so the magic number is always last. */
/* Magic number for compat checking */

@@ -362,6 +368,9 @@ extern enum language set_language (enum
#define LA_EMIT_CHAR(ch, stream, quoter) \
(current_language->la_emitchar(ch, stream, quoter))

+#define LA_PRINT_ARRAY_INDEX(index_value, stream, format, pretty) \
+ (current_language->la_print_array_index(index_value, stream, format, pretty))
+
/* Test a character to decide whether it can be printed in literal form
or needs to be printed in another representation. For example,
in C the literal form of the character with octal value 141 is 'a'
@@ -457,4 +466,10 @@ extern char *language_class_name_from_ph
/* Splitting strings into words. */
extern char *default_word_break_characters (void);

+/* Print the index of an array element using the C99 syntax. */
+extern void default_print_array_index (struct value *index_value,
+ struct ui_file *stream,
+ int format,
+ enum val_prettyprint pretty);
+
#endif /* defined (LANGUAGE_H) */
Index: language.c
===================================================================
RCS file: /cvs/src/src/gdb/language.c,v
retrieving revision 1.62
diff -u -p -r1.62 language.c
--- language.c 29 Aug 2005 12:57:49 -0000 1.62
+++ language.c 3 Oct 2005 06:13:29 -0000
@@ -1057,6 +1057,17 @@ default_word_break_characters (void)
return " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
}

+/* Print the index of array elements using the C99 syntax. */
+
+void
+default_print_array_index (struct value *index_value, struct ui_file *stream,
+ int format, enum val_prettyprint pretty)
+{
+ fprintf_filtered (stream, "[");
+ LA_VALUE_PRINT (index_value, stream, format, pretty);
+ fprintf_filtered (stream, "] = ");
+}
+
/* Define the language that is no language. */

static int
@@ -1181,6 +1192,7 @@ const struct language_defn unknown_langu
NULL,
default_word_break_characters,
unknown_language_arch_info, /* la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -1217,6 +1229,7 @@ const struct language_defn auto_language
NULL,
default_word_break_characters,
unknown_language_arch_info, /* la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -1252,6 +1265,7 @@ const struct language_defn local_languag
NULL,
default_word_break_characters,
unknown_language_arch_info, /* la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};
\f
Index: ada-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-lang.c,v
retrieving revision 1.78
diff -u -p -r1.78 ada-lang.c
--- ada-lang.c 9 May 2005 21:20:29 -0000 1.78
+++ ada-lang.c 3 Oct 2005 06:13:34 -0000
@@ -303,6 +303,16 @@ ada_get_gdb_completer_word_break_charact
return ada_completer_word_break_characters;
}

+/* Print an array element index using the Ada syntax. */
+
+static void
+ada_print_array_index (struct value *index_value, struct ui_file *stream,
+ int format, enum val_prettyprint pretty)
+{
+ LA_VALUE_PRINT (index_value, stream, format, pretty);
+ fprintf_filtered (stream, " => ");
+}
+
/* Read the string located at ADDR from the inferior and store the
result into BUF. */

@@ -8766,6 +8776,7 @@ const struct language_defn ada_language_
NULL,
ada_get_gdb_completer_word_break_characters,
ada_language_arch_info,
+ ada_print_array_index,
LANG_MAGIC
};

Index: c-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/c-lang.c,v
retrieving revision 1.37
diff -u -p -r1.37 c-lang.c
--- c-lang.c 9 May 2005 21:20:30 -0000 1.37
+++ c-lang.c 3 Oct 2005 06:13:34 -0000
@@ -595,6 +595,7 @@ const struct language_defn c_language_de
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

@@ -653,6 +654,7 @@ const struct language_defn cplus_languag
&builtin_type_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -688,6 +690,7 @@ const struct language_defn asm_language_
NULL,
default_word_break_characters,
c_language_arch_info, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

@@ -728,6 +731,7 @@ const struct language_defn minimal_langu
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

Index: f-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/f-lang.c,v
retrieving revision 1.31
diff -u -p -r1.31 f-lang.c
--- f-lang.c 9 May 2005 21:20:30 -0000 1.31
+++ f-lang.c 3 Oct 2005 06:13:35 -0000
@@ -485,6 +485,7 @@ const struct language_defn f_language_de
&builtin_type_f_character, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: jv-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-lang.c,v
retrieving revision 1.42
diff -u -p -r1.42 jv-lang.c
--- jv-lang.c 27 May 2005 04:39:32 -0000 1.42
+++ jv-lang.c 3 Oct 2005 06:13:36 -0000
@@ -1114,6 +1114,7 @@ const struct language_defn java_language
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

Index: m2-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/m2-lang.c,v
retrieving revision 1.23
diff -u -p -r1.23 m2-lang.c
--- m2-lang.c 9 May 2005 21:20:34 -0000 1.23
+++ m2-lang.c 3 Oct 2005 06:13:36 -0000
@@ -437,6 +437,7 @@ const struct language_defn m2_language_d
&builtin_type_m2_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: objc-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/objc-lang.c,v
retrieving revision 1.49
diff -u -p -r1.49 objc-lang.c
--- objc-lang.c 12 Jul 2005 12:11:44 -0000 1.49
+++ objc-lang.c 3 Oct 2005 06:13:36 -0000
@@ -684,6 +684,7 @@ const struct language_defn objc_language
&builtin_type_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: p-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/p-lang.c,v
retrieving revision 1.25
diff -u -p -r1.25 p-lang.c
--- p-lang.c 9 May 2005 21:20:34 -0000 1.25
+++ p-lang.c 3 Oct 2005 06:13:37 -0000
@@ -477,6 +477,7 @@ const struct language_defn pascal_langua
&builtin_type_char, /* Type of string elements */
default_word_break_characters,
NULL, /* FIXME: la_language_arch_info. */
+ default_print_array_index,
LANG_MAGIC
};

Index: scm-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-lang.c,v
retrieving revision 1.32
diff -u -p -r1.32 scm-lang.c
--- scm-lang.c 27 May 2005 04:39:32 -0000 1.32
+++ scm-lang.c 3 Oct 2005 06:13:37 -0000
@@ -269,6 +269,7 @@ const struct language_defn scm_language_
NULL,
default_word_break_characters,
c_language_arch_info,
+ default_print_array_index,
LANG_MAGIC
};

Index: valprint.h
===================================================================
RCS file: /cvs/src/src/gdb/valprint.h,v
retrieving revision 1.10
diff -u -p -r1.10 valprint.h
--- valprint.h 9 May 2005 21:20:35 -0000 1.10
+++ valprint.h 3 Oct 2005 06:13:37 -0000
@@ -50,6 +50,14 @@ extern int output_format;

extern int stop_print_at_null; /* Stop printing at null char? */

+extern int print_array_indexes_p (void);
+
+extern int get_array_low_bound (struct type *type, long *low_bound);
+
+extern void maybe_print_array_index (struct type *index_type, LONGEST index,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty);
+
extern void val_print_array_elements (struct type *, const gdb_byte *,
CORE_ADDR, struct ui_file *, int,
int, int, enum val_prettyprint,
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.54
diff -u -p -r1.54 valprint.c
--- valprint.c 10 Jun 2005 06:07:32 -0000 1.54
+++ valprint.c 3 Oct 2005 06:13:38 -0000
@@ -100,6 +100,17 @@ Default output radix for printing of val
}
int output_format = 0;

+/* By default we print arrays without printing the index of each element in
+ the array. This behavior can be changed by setting PRINT_ARRAY_INDEXES. */
+
+static int print_array_indexes = 0;
+static void
+show_print_array_indexes (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
+}
+
/* Print repeat counts if there are more than this many repetitions of an
element in an array. Referenced by the low level language dependent
print routines. */
@@ -859,6 +870,62 @@ print_char_chars (struct ui_file *stream
}
}

+/* Return non-zero if the debugger should print the index of each element
+ when printing array values. */
+
+int
+print_array_indexes_p (void)
+{
+ return print_array_indexes;
+}
+
+/* Assuming TYPE is a simple, non-empty array type, compute its lower bound.
+ Save it into LOW_BOUND if not NULL.
+
+ Return 1 if the operation was successful. Return zero otherwise,
+ in which case the value of LOW_BOUND is unmodified. */
+
+int
+get_array_low_bound (struct type *type, long *low_bound)
+{
+ struct type *index = TYPE_INDEX_TYPE (type);
+ long low = 0;
+
+ if (index == NULL)
+ return 0;
+
+ if (TYPE_CODE (index) != TYPE_CODE_RANGE
+ && TYPE_CODE (index) != TYPE_CODE_ENUM)
+ return 0;
+
+ low = TYPE_LOW_BOUND (index);
+ if (low > TYPE_HIGH_BOUND (index))
+ return 0;
+
+ if (low_bound)
+ *low_bound = low;
+
+ return 1;
+}
+
+/* Print on STREAM using the given FORMAT the index for the element
+ at INDEX of an array whose index type is INDEX_TYPE. */
+
+void
+maybe_print_array_index (struct type *index_type, LONGEST index,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct value *index_value;
+
+ if (!print_array_indexes)
+ return;
+
+ index_value = value_from_longest (index_type, index);
+
+ LA_PRINT_ARRAY_INDEX (index_value, stream, format, pretty);
+}
+
/* Called by various <lang>_val_print routines to print elements of an
array in the form "<elem1>, <elem2>, <elem3>, ...".

@@ -877,17 +944,25 @@ val_print_array_elements (struct type *t
{
unsigned int things_printed = 0;
unsigned len;
- struct type *elttype;
+ struct type *elttype, *index_type;
unsigned eltlen;
/* Position of the array element we are examining to see
whether it is repeated. */
unsigned int rep1;
/* Number of repetitions we have detected so far. */
unsigned int reps;
+ long low_bound_index;
+
+ if (!get_array_low_bound (type, &low_bound_index))
+ {
+ warning ("unable to get low bound of array, using zero as default");
+ low_bound_index = 0;
+ }

elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (check_typedef (elttype));
len = TYPE_LENGTH (type) / eltlen;
+ index_type = TYPE_INDEX_TYPE (type);

annotate_array_section_begin (i, elttype);

@@ -906,6 +981,8 @@ val_print_array_elements (struct type *t
}
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, i + low_bound_index,
+ stream, format, pretty);

rep1 = i + 1;
reps = 1;
@@ -1396,6 +1473,12 @@ Show the default input and output number
Use 'show input-radix' or 'show output-radix' to independently show each."),
&showlist);

+ add_setshow_boolean_cmd ("array-indexes", class_support,
+ &print_array_indexes, _("\
+Set printing of array indexes."), _("\
+Show printing of array indexes"), NULL, NULL, show_print_array_indexes,
+ &setprintlist, &showprintlist);
+
/* Give people the defaults which they are used to. */
prettyprint_structs = 0;
prettyprint_arrays = 0;
Index: ada-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-valprint.c,v
retrieving revision 1.23
diff -u -p -r1.23 ada-valprint.c
--- ada-valprint.c 9 May 2005 21:20:30 -0000 1.23
+++ ada-valprint.c 3 Oct 2005 06:13:38 -0000
@@ -86,21 +86,14 @@ print_optional_low_bound (struct ui_file
struct type *index_type;
long low_bound;

- index_type = TYPE_INDEX_TYPE (type);
- low_bound = 0;
-
- if (index_type == NULL)
+ if (print_array_indexes_p ())
return 0;
- if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
- {
- low_bound = TYPE_LOW_BOUND (index_type);
- if (low_bound > TYPE_HIGH_BOUND (index_type))
- return 0;
- index_type = TYPE_TARGET_TYPE (index_type);
- }
- else
+
+ if (!get_array_low_bound (type, &low_bound))
return 0;

+ index_type = TYPE_INDEX_TYPE (type);
+
switch (TYPE_CODE (index_type))
{
case TYPE_CODE_ENUM:
@@ -137,16 +130,18 @@ val_print_packed_array_elements (struct
unsigned int i;
unsigned int things_printed = 0;
unsigned len;
- struct type *elttype;
+ struct type *elttype, *index_type;
unsigned eltlen;
unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0);
struct value *mark = value_mark ();
+ LONGEST low = 0;

elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (check_typedef (elttype));
+ index_type = TYPE_INDEX_TYPE (type);

{
- LONGEST low, high;
+ LONGEST high;
if (get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low, &high) < 0)
len = 1;
else
@@ -174,6 +169,7 @@ val_print_packed_array_elements (struct
}
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, i + low, stream, format, pretty);

i0 = i;
v0 = ada_value_primitive_packed_val (NULL, valaddr,
@@ -219,6 +215,8 @@ val_print_packed_array_elements (struct
fprintf_filtered (stream, ", ");
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, j + low,
+ stream, format, pretty);
}
val_print (elttype, value_contents (v0), 0, 0, stream, format,
0, recurse + 1, pretty);