Add support for dynamic type lengths
In Ada, a type with variant parts can have a variable length. This patch adds support for this to gdb, by integrating the length computation into the dynamic type resolution code. gdb/ChangeLog 2020-04-24 Tom Tromey <tromey@adacore.com> * dwarf2/read.c (read_structure_type): Handle dynamic length. * gdbtypes.c (is_dynamic_type_internal): Check TYPE_HAS_DYNAMIC_LENGTH. (resolve_dynamic_type_internal): Use TYPE_DYNAMIC_LENGTH. * gdbtypes.h (TYPE_HAS_DYNAMIC_LENGTH, TYPE_DYNAMIC_LENGTH): New macros. (enum dynamic_prop_node_kind) <DYN_PROP_BYTE_SIZE>: New constant. gdb/testsuite/ChangeLog 2020-04-24 Tom Tromey <tromey@adacore.com> * gdb.ada/variant.exp: New file * gdb.ada/variant/pkg.adb: New file * gdb.ada/variant/pck.adb: New file
This commit is contained in:
parent
9c6a1327ad
commit
f8e89861cf
|
@ -1,3 +1,14 @@
|
||||||
|
2020-04-24 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
|
* dwarf2/read.c (read_structure_type): Handle dynamic length.
|
||||||
|
* gdbtypes.c (is_dynamic_type_internal): Check
|
||||||
|
TYPE_HAS_DYNAMIC_LENGTH.
|
||||||
|
(resolve_dynamic_type_internal): Use TYPE_DYNAMIC_LENGTH.
|
||||||
|
* gdbtypes.h (TYPE_HAS_DYNAMIC_LENGTH, TYPE_DYNAMIC_LENGTH):
|
||||||
|
New macros.
|
||||||
|
(enum dynamic_prop_node_kind) <DYN_PROP_BYTE_SIZE>: New
|
||||||
|
constant.
|
||||||
|
|
||||||
2020-04-24 Tom Tromey <tromey@adacore.com>
|
2020-04-24 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
* dwarf2/read.c (struct variant_field): Rewrite.
|
* dwarf2/read.c (struct variant_field): Rewrite.
|
||||||
|
|
|
@ -15300,14 +15300,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
TYPE_LENGTH (type) = DW_UNSND (attr);
|
TYPE_LENGTH (type) = DW_UNSND (attr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* For the moment, dynamic type sizes are not supported
|
struct dynamic_prop prop;
|
||||||
by GDB's struct type. The actual size is determined
|
if (attr_to_dynamic_prop (attr, die, cu, &prop,
|
||||||
on-demand when resolving the type of a given object,
|
cu->per_cu->addr_type ()))
|
||||||
so set the type's length to zero for now. Otherwise,
|
add_dyn_prop (DYN_PROP_BYTE_SIZE, prop, type);
|
||||||
we record an expression as the length, and that expression
|
|
||||||
could lead to a very large value, which could eventually
|
|
||||||
lead to us trying to allocate that much memory when creating
|
|
||||||
a value of that type. */
|
|
||||||
TYPE_LENGTH (type) = 0;
|
TYPE_LENGTH (type) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1975,6 +1975,9 @@ is_dynamic_type_internal (struct type *type, int top_level)
|
||||||
if (prop != nullptr && prop->kind != PROP_TYPE)
|
if (prop != nullptr && prop->kind != PROP_TYPE)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (TYPE_HAS_DYNAMIC_LENGTH (type))
|
||||||
|
return 1;
|
||||||
|
|
||||||
switch (TYPE_CODE (type))
|
switch (TYPE_CODE (type))
|
||||||
{
|
{
|
||||||
case TYPE_CODE_RANGE:
|
case TYPE_CODE_RANGE:
|
||||||
|
@ -2491,13 +2494,19 @@ resolve_dynamic_type_internal (struct type *type,
|
||||||
int top_level)
|
int top_level)
|
||||||
{
|
{
|
||||||
struct type *real_type = check_typedef (type);
|
struct type *real_type = check_typedef (type);
|
||||||
struct type *resolved_type = type;
|
struct type *resolved_type = nullptr;
|
||||||
struct dynamic_prop *prop;
|
struct dynamic_prop *prop;
|
||||||
CORE_ADDR value;
|
CORE_ADDR value;
|
||||||
|
|
||||||
if (!is_dynamic_type_internal (real_type, top_level))
|
if (!is_dynamic_type_internal (real_type, top_level))
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
|
gdb::optional<CORE_ADDR> type_length;
|
||||||
|
prop = TYPE_DYNAMIC_LENGTH (type);
|
||||||
|
if (prop != NULL
|
||||||
|
&& dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
|
||||||
|
type_length = value;
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||||
{
|
{
|
||||||
resolved_type = copy_type (type);
|
resolved_type = copy_type (type);
|
||||||
|
@ -2553,6 +2562,15 @@ resolve_dynamic_type_internal (struct type *type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resolved_type == nullptr)
|
||||||
|
return type;
|
||||||
|
|
||||||
|
if (type_length.has_value ())
|
||||||
|
{
|
||||||
|
TYPE_LENGTH (resolved_type) = *type_length;
|
||||||
|
remove_dyn_prop (DYN_PROP_BYTE_SIZE, resolved_type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Resolve data_location attribute. */
|
/* Resolve data_location attribute. */
|
||||||
prop = TYPE_DATA_LOCATION (resolved_type);
|
prop = TYPE_DATA_LOCATION (resolved_type);
|
||||||
if (prop != NULL
|
if (prop != NULL
|
||||||
|
|
|
@ -355,6 +355,10 @@ DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags);
|
||||||
#define TYPE_HAS_VARIANT_PARTS(t) \
|
#define TYPE_HAS_VARIANT_PARTS(t) \
|
||||||
(get_dyn_prop (DYN_PROP_VARIANT_PARTS, t) != nullptr)
|
(get_dyn_prop (DYN_PROP_VARIANT_PARTS, t) != nullptr)
|
||||||
|
|
||||||
|
/* * True if this type has a dynamic length. */
|
||||||
|
#define TYPE_HAS_DYNAMIC_LENGTH(t) \
|
||||||
|
(get_dyn_prop (DYN_PROP_BYTE_SIZE, t) != nullptr)
|
||||||
|
|
||||||
/* * Instruction-space delimited type. This is for Harvard architectures
|
/* * Instruction-space delimited type. This is for Harvard architectures
|
||||||
which have separate instruction and data address spaces (and perhaps
|
which have separate instruction and data address spaces (and perhaps
|
||||||
others).
|
others).
|
||||||
|
@ -552,6 +556,9 @@ enum dynamic_prop_node_kind
|
||||||
|
|
||||||
/* A property holding variant parts. */
|
/* A property holding variant parts. */
|
||||||
DYN_PROP_VARIANT_PARTS,
|
DYN_PROP_VARIANT_PARTS,
|
||||||
|
|
||||||
|
/* A property holding the size of the type. */
|
||||||
|
DYN_PROP_BYTE_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* * List for dynamic type attributes. */
|
/* * List for dynamic type attributes. */
|
||||||
|
@ -1445,6 +1452,8 @@ extern bool set_type_align (struct type *, ULONGEST);
|
||||||
TYPE_DATA_LOCATION (thistype)->data.const_val
|
TYPE_DATA_LOCATION (thistype)->data.const_val
|
||||||
#define TYPE_DATA_LOCATION_KIND(thistype) \
|
#define TYPE_DATA_LOCATION_KIND(thistype) \
|
||||||
TYPE_DATA_LOCATION (thistype)->kind
|
TYPE_DATA_LOCATION (thistype)->kind
|
||||||
|
#define TYPE_DYNAMIC_LENGTH(thistype) \
|
||||||
|
get_dyn_prop (DYN_PROP_BYTE_SIZE, thistype)
|
||||||
|
|
||||||
/* Property accessors for the type allocated/associated. */
|
/* Property accessors for the type allocated/associated. */
|
||||||
#define TYPE_ALLOCATED_PROP(thistype) \
|
#define TYPE_ALLOCATED_PROP(thistype) \
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2020-04-24 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
|
* gdb.ada/variant.exp: New file
|
||||||
|
* gdb.ada/variant/pkg.adb: New file
|
||||||
|
* gdb.ada/variant/pck.adb: New file
|
||||||
|
|
||||||
2020-04-24 Tom de Vries <tdevries@suse.de>
|
2020-04-24 Tom de Vries <tdevries@suse.de>
|
||||||
|
|
||||||
* lib/gdb.exp (clean_restart): Reset errcnt and warncnt.
|
* lib/gdb.exp (clean_restart): Reset errcnt and warncnt.
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Copyright 2020 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
load_lib "ada.exp"
|
||||||
|
|
||||||
|
standard_ada_testfile pkg
|
||||||
|
|
||||||
|
foreach_with_prefix scenario {none all minimal} {
|
||||||
|
set flags {debug}
|
||||||
|
if {$scenario != "none"} {
|
||||||
|
lappend flags additional_flags=-fgnat-encodings=$scenario
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
set bp_location [gdb_get_line_number "STOP" ${testdir}/pkg.adb]
|
||||||
|
runto "pkg.adb:$bp_location"
|
||||||
|
|
||||||
|
gdb_test "print r" "= \\(c => 100 'd'\\)"
|
||||||
|
gdb_test "print q" " = \\(c => 0 '\\\[\"00\"\\\]', x_first => 27\\)"
|
||||||
|
|
||||||
|
gdb_test "print st1" " = \\(i => -4, one => 1, x => 2\\)"
|
||||||
|
gdb_test "print st2" " = \\(i => 99, one => 1, y => 77\\)"
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
-- Copyright 2020 Free Software Foundation, Inc.
|
||||||
|
--
|
||||||
|
-- This program is free software; you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation; either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package Pck is
|
||||||
|
|
||||||
|
type Rec_Type (C : Character := 'd') is record
|
||||||
|
case C is
|
||||||
|
when Character'First => X_First : Integer;
|
||||||
|
when Character'Val (127) => X_127 : Integer;
|
||||||
|
when Character'Val (128) => X_128 : Integer;
|
||||||
|
when Character'Last => X_Last : Integer;
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type Second_Type (I : Integer) is record
|
||||||
|
One: Integer;
|
||||||
|
case I is
|
||||||
|
when -5 .. 5 =>
|
||||||
|
X : Integer;
|
||||||
|
when others =>
|
||||||
|
Y : Integer;
|
||||||
|
end case;
|
||||||
|
end record;
|
||||||
|
end Pck;
|
|
@ -0,0 +1,30 @@
|
||||||
|
-- Copyright 2020 Free Software Foundation, Inc.
|
||||||
|
--
|
||||||
|
-- This program is free software; you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation; either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
with Pck; use Pck;
|
||||||
|
|
||||||
|
procedure Pkg is
|
||||||
|
|
||||||
|
R, Q : Rec_Type;
|
||||||
|
|
||||||
|
ST1 : constant Second_Type := (I => -4, One => 1, X => 2);
|
||||||
|
ST2 : constant Second_Type := (I => 99, One => 1, Y => 77);
|
||||||
|
|
||||||
|
begin
|
||||||
|
R := (C => 'd');
|
||||||
|
Q := (C => Character'First, X_First => 27);
|
||||||
|
|
||||||
|
null; -- STOP
|
||||||
|
end Pkg;
|
Loading…
Reference in New Issue