diff options
author | Tom Tromey <tromey@adacore.com> | 2020-11-04 08:49:16 -0700 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2020-11-04 08:49:17 -0700 |
commit | 575673752cade1772f4a6ba2e38306e5ac9a91f6 (patch) | |
tree | d84eec349be4566a38181d48fdf9fcca42c29af0 /gdb/ada-lang.c | |
parent | a7400e443cb4c20aea2c1c4641cb56a913ff7235 (diff) | |
download | gdb-575673752cade1772f4a6ba2e38306e5ac9a91f6.zip gdb-575673752cade1772f4a6ba2e38306e5ac9a91f6.tar.gz gdb-575673752cade1772f4a6ba2e38306e5ac9a91f6.tar.bz2 |
Synthesize array descriptors with -fgnat-encodings=minimal
When -fgnat-encodings=minimal, the compiler will avoid the special
GNAT-specific "encodings" format, and instead emit ordinary DWARF as
much as possible.
When emitting DWARF for thick pointers to arrays, the compiler emits
something like:
<1><11db>: Abbrev Number: 7 (DW_TAG_array_type)
<11dc> DW_AT_name : (indirect string, offset: 0x1bb8): string
<11e0> DW_AT_data_location: 2 byte block: 97 6
(DW_OP_push_object_address; DW_OP_deref)
<11e3> DW_AT_type : <0x1173>
<11e7> DW_AT_sibling : <0x1201>
<2><11eb>: Abbrev Number: 8 (DW_TAG_subrange_type)
<11ec> DW_AT_type : <0x1206>
<11f0> DW_AT_lower_bound : 6 byte block: 97 23 8 6 94 4
(DW_OP_push_object_address; DW_OP_plus_uconst: 8; DW_OP_deref;
DW_OP_deref_size: 4)
<11f7> DW_AT_upper_bound : 8 byte block: 97 23 8 6 23 4 94 4
(DW_OP_push_object_address; DW_OP_plus_uconst: 8; DW_OP_deref;
DW_OP_plus_uconst: 4; DW_OP_deref_size: 4)
If you read between the lines, the "array" is actually a structure
with two elements. One element is a pointer to the array data, and
the other structure describes the bounds of the array. However, the
compiler doesn't emit this explicitly, but instead hides it behind
these location expressions.
gdb can print such objects, but currently there is no way to construct
one. So, this patch adds some code to the DWARF reader to recognize
this construct, and then synthesize an array descriptor. This
descriptor is then handled by the existing Ada code.
Internally, we've modified GCC to emit the structure type explicitly
(we will of course be sending this upstream). In this case, the array
still has the DW_AT_data_location, though. This patch also modifies
gdb to ignore the data location in this case -- this is preferred
because the location only serves to confuse the Ada code that already
knows where to find the data. In the future I hope to move some of
this handling to the gdb core, so that Ada-specific hacks are not
needed; however I have not yet done this.
Because parallel types are not emitted with -fgnat-encodings=minimal,
some changes to the Ada code were also required.
The change ina ada-valprint.c was needed to avoid infinite recursion
when trying to print a constrained packed array. And, there didn't
seem to be any need for a recursive call here -- the value could
simply be returned instead.
Finally, gdb.ada/frame_arg_lang.exp no longer works in C mode, because
we drop back to the structure approach now. As mentioned earlier,
future work should probably fix this again; meanwhile, this doesn't
seem to be a big problem, because it is what is currently done (users
as a rule don't use -fgnat-encodings=minimal -- which is what I am
ultimately trying to fix).
Note that a couple of tests have an added KFAIL. Some
-fgnat-encodings=minimal changes have landed in GNAT, and you need
something very recent to pass all the tests. I'm using git gcc to
accomplish this.
gdb/ChangeLog
2020-11-04 Tom Tromey <tromey@adacore.com>
* dwarf2/read.c (recognize_bound_expression)
(quirk_ada_thick_pointer): New functions.
(read_array_type): Call quirk_ada_thick_pointer.
(set_die_type): Add "skip_data_location" parameter.
(quirk_ada_thick_pointer): New function.
(process_structure_scope): Call quirk_ada_thick_pointer.
* ada-lang.c (ada_is_unconstrained_packed_array_type)
(decode_packed_array_bitsize): Handle thick pointers without
parallel types.
(ada_is_gnat_encoded_packed_array_type): Rename from
ada_is_packed_array_type.
(ada_is_constrained_packed_array_type): Update.
* ada-valprint.c (ada_val_print_gnat_array): Remove.
(ada_value_print_1): Use ada_get_decoded_value.
gdb/testsuite/ChangeLog
2020-11-04 Tom Tromey <tromey@adacore.com>
* gdb.ada/O2_float_param.exp: Test different -fgnat-encodings
values.
* gdb.ada/access_to_unbounded_array.exp: Test different
-fgnat-encodings values.
* gdb.ada/big_packed_array.exp: Test different -fgnat-encodings
values.
* gdb.ada/arr_enum_idx_w_gap.exp: Test different -fgnat-encodings
values.
* gdb.ada/array_ptr_renaming.exp: Test different -fgnat-encodings
values.
* gdb.ada/array_of_variable_length.exp: Test different
-fgnat-encodings values.
* gdb.ada/arrayparam.exp: Test different -fgnat-encodings values.
* gdb.ada/arrayptr.exp: Test different -fgnat-encodings values.
* gdb.ada/frame_arg_lang.exp: Revert -fgnat-encodings=minimal
change.
* gdb.ada/mi_string_access.exp: Test different -fgnat-encodings
values.
* gdb.ada/mod_from_name.exp: Test different -fgnat-encodings values.
* gdb.ada/out_of_line_in_inlined.exp: Test different
-fgnat-encodings values.
* gdb.ada/packed_array.exp: Test different -fgnat-encodings
values.
* gdb.ada/pckd_arr_ren.exp: Test different -fgnat-encodings
values.
* gdb.ada/unc_arr_ptr_in_var_rec.exp: Test different
-fgnat-encodings values.
* gdb.ada/variant_record_packed_array.exp: Test different
-fgnat-encodings values.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r-- | gdb/ada-lang.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 93d8225..f6043b5 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -170,8 +170,6 @@ static long decode_packed_array_bitsize (struct type *); static struct value *decode_constrained_packed_array (struct value *); -static int ada_is_packed_array_type (struct type *); - static int ada_is_unconstrained_packed_array_type (struct type *); static struct value *value_subscript_packed (struct value *, int, @@ -1965,7 +1963,7 @@ ada_coerce_to_simple_array_type (struct type *type) /* Non-zero iff TYPE represents a standard GNAT packed-array type. */ static int -ada_is_packed_array_type (struct type *type) +ada_is_gnat_encoded_packed_array_type (struct type *type) { if (type == NULL) return 0; @@ -1982,7 +1980,7 @@ ada_is_packed_array_type (struct type *type) int ada_is_constrained_packed_array_type (struct type *type) { - return ada_is_packed_array_type (type) + return ada_is_gnat_encoded_packed_array_type (type) && !ada_is_array_descriptor_type (type); } @@ -1992,8 +1990,26 @@ ada_is_constrained_packed_array_type (struct type *type) static int ada_is_unconstrained_packed_array_type (struct type *type) { - return ada_is_packed_array_type (type) - && ada_is_array_descriptor_type (type); + if (!ada_is_array_descriptor_type (type)) + return 0; + + if (ada_is_gnat_encoded_packed_array_type (type)) + return 1; + + /* If we saw GNAT encodings, then the above code is sufficient. + However, with minimal encodings, we will just have a thick + pointer instead. */ + if (is_thick_pntr (type)) + { + type = desc_base_type (type); + /* The structure's first field is a pointer to an array, so this + fetches the array type. */ + type = TYPE_TARGET_TYPE (type->field (0).type ()); + /* Now we can see if the array elements are packed. */ + return TYPE_FIELD_BITSIZE (type, 0) > 0; + } + + return 0; } /* Given that TYPE encodes a packed array type (constrained or unconstrained), @@ -2020,7 +2036,15 @@ decode_packed_array_bitsize (struct type *type) return 0; tail = strstr (raw_name, "___XP"); - gdb_assert (tail != NULL); + if (tail == nullptr) + { + gdb_assert (is_thick_pntr (type)); + /* The structure's first field is a pointer to an array, so this + fetches the array type. */ + type = TYPE_TARGET_TYPE (type->field (0).type ()); + /* Now we can see if the array elements are packed. */ + return TYPE_FIELD_BITSIZE (type, 0); + } if (sscanf (tail + sizeof ("___XP") - 1, "%ld", &bits) != 1) { |