aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbtypes.c
diff options
context:
space:
mode:
authorJerome Guitton <guitton@adacore.com>2015-03-27 14:45:08 +0100
committerJoel Brobecker <brobecker@adacore.com>2015-05-15 14:03:46 -0700
commitaa7151351ed16c5a4eb1334c9a1af1b06dbb7a99 (patch)
tree44c933eb16bda42b110800a9e3cce8ce744a5174 /gdb/gdbtypes.c
parent931e5bc3e19d1e279fc28c5cf5571f812c79b8d3 (diff)
downloadfsf-binutils-gdb-aa7151351ed16c5a4eb1334c9a1af1b06dbb7a99.zip
fsf-binutils-gdb-aa7151351ed16c5a4eb1334c9a1af1b06dbb7a99.tar.gz
fsf-binutils-gdb-aa7151351ed16c5a4eb1334c9a1af1b06dbb7a99.tar.bz2
Array indexed by non-contiguous enumeration types
In Ada, index types of arrays can be enumeration types, and enumeration types can be non-contiguous. In which case the address of elements is not given by the value of the index, but by its position in the enumeration type. In other words, in this example: type Color is (Blue, Red); for Color use (Blue => 8, Red => 12, Green => 16); type A is array (Color) of Integer; type B is array (1 .. 3) of Integer; Arrays of type A and B will have the same layout in memory, even if the enumeration Color has a hole in its set of integer value. Since recently support for such a feature was in ada-lang.c, where the array was casted to a regular continuous index range. We were losing the information of index type. And this was not quite working for subranges in variable-length fields; their bounds are expressed using the integer value of the bounds, not its position in the enumeration, and there was some confusion all over ada-lang.c as to whether we had the position or the integer value was used for indexes. The idea behind this patch is to clean this up by keeping the real representation of these array index types and bounds when representing the value, and only use the position when accessing the elements or computing the length. This first patch fixes the printing of such an array. To the best of my knowledge, this feature only exists in Ada so it should only affect this language. gdb/ChangeLog: Jerome Guitton <guitton@adacore.com>: * ada-lang.c (ada_value_ptr_subscript): Use enum position of index to get element instead of enum value. (ada_value_slice_from_ptr, ada_value_slice): Use enum position of index to compute length, but enum values to compute bounds. (ada_array_length): Use enum position of index instead of enum value. (pos_atr): Move position computation to... (ada_evaluate_subexp): Use enum values to compute bounds. * gdbtypes.c (discrete_position): ...this new function. * gdbtypes.h (discrete_position): New function declaration. * valprint.c (val_print_array_elements): Call discrete_position to handle array indexed by non-contiguous enumeration types. gdb/testsuite/ChangeLog: * gdb.ada/arr_enum_with_gap: New testcase.
Diffstat (limited to 'gdb/gdbtypes.c')
-rw-r--r--gdb/gdbtypes.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 4bbfc75..ca86fbd 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1004,6 +1004,45 @@ get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
return 1;
}
+/* Assuming that TYPE is a discrete type and VAL is a valid integer
+ representation of a value of this type, save the corresponding
+ position number in POS.
+
+ Its differs from VAL only in the case of enumeration types. In
+ this case, the position number of the value of the first listed
+ enumeration literal is zero; the position number of the value of
+ each subsequent enumeration literal is one more than that of its
+ predecessor in the list.
+
+ Return 1 if the operation was successful. Return zero otherwise,
+ in which case the value of POS is unmodified.
+*/
+
+int
+discrete_position (struct type *type, LONGEST val, LONGEST *pos)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+ {
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (type); i += 1)
+ {
+ if (val == TYPE_FIELD_ENUMVAL (type, i))
+ {
+ *pos = i;
+ return 1;
+ }
+ }
+ /* Invalid enumeration value. */
+ return 0;
+ }
+ else
+ {
+ *pos = val;
+ return 1;
+ }
+}
+
/* Create an array type using either a blank type supplied in
RESULT_TYPE, or creating a new type, inheriting the objfile from
RANGE_TYPE.