aboutsummaryrefslogtreecommitdiff
path: root/gdb/ada-lang.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2020-11-04 08:49:16 -0700
committerTom Tromey <tromey@adacore.com>2020-11-04 08:49:17 -0700
commit575673752cade1772f4a6ba2e38306e5ac9a91f6 (patch)
treed84eec349be4566a38181d48fdf9fcca42c29af0 /gdb/ada-lang.c
parenta7400e443cb4c20aea2c1c4641cb56a913ff7235 (diff)
downloadgdb-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.c38
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)
{