aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/dwarf2/read.c12
-rw-r--r--gdb/gdbtypes.c20
-rw-r--r--gdb/gdbtypes.h9
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.ada/variant.exp40
-rw-r--r--gdb/testsuite/gdb.ada/variant/pck.ads37
-rw-r--r--gdb/testsuite/gdb.ada/variant/pkg.adb30
8 files changed, 156 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 962c997..29e9a47 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
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>
+
* dwarf2/read.c (struct variant_field): Rewrite.
(struct variant_part_builder): New.
(struct nextfield): Remove "variant" field. Add "offset".
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index dd808e0..f6d0624 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -15300,14 +15300,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_LENGTH (type) = DW_UNSND (attr);
else
{
- /* For the moment, dynamic type sizes are not supported
- by GDB's struct type. The actual size is determined
- on-demand when resolving the type of a given object,
- so set the type's length to zero for now. Otherwise,
- 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. */
+ struct dynamic_prop prop;
+ if (attr_to_dynamic_prop (attr, die, cu, &prop,
+ cu->per_cu->addr_type ()))
+ add_dyn_prop (DYN_PROP_BYTE_SIZE, prop, type);
TYPE_LENGTH (type) = 0;
}
}
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 1bd9d8a..6d755e9 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1975,6 +1975,9 @@ is_dynamic_type_internal (struct type *type, int top_level)
if (prop != nullptr && prop->kind != PROP_TYPE)
return 1;
+ if (TYPE_HAS_DYNAMIC_LENGTH (type))
+ return 1;
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
@@ -2491,13 +2494,19 @@ resolve_dynamic_type_internal (struct type *type,
int top_level)
{
struct type *real_type = check_typedef (type);
- struct type *resolved_type = type;
+ struct type *resolved_type = nullptr;
struct dynamic_prop *prop;
CORE_ADDR value;
if (!is_dynamic_type_internal (real_type, top_level))
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)
{
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. */
prop = TYPE_DATA_LOCATION (resolved_type);
if (prop != NULL
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 1345158..87b1bca 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -355,6 +355,10 @@ DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags);
#define TYPE_HAS_VARIANT_PARTS(t) \
(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
which have separate instruction and data address spaces (and perhaps
others).
@@ -552,6 +556,9 @@ enum dynamic_prop_node_kind
/* A property holding variant parts. */
DYN_PROP_VARIANT_PARTS,
+
+ /* A property holding the size of the type. */
+ DYN_PROP_BYTE_SIZE,
};
/* * List for dynamic type attributes. */
@@ -1445,6 +1452,8 @@ extern bool set_type_align (struct type *, ULONGEST);
TYPE_DATA_LOCATION (thistype)->data.const_val
#define TYPE_DATA_LOCATION_KIND(thistype) \
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. */
#define TYPE_ALLOCATED_PROP(thistype) \
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7426bdd..6664700 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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>
* lib/gdb.exp (clean_restart): Reset errcnt and warncnt.
diff --git a/gdb/testsuite/gdb.ada/variant.exp b/gdb/testsuite/gdb.ada/variant.exp
new file mode 100644
index 0000000..b68bf60
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/variant.exp
@@ -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\\)"
+}
diff --git a/gdb/testsuite/gdb.ada/variant/pck.ads b/gdb/testsuite/gdb.ada/variant/pck.ads
new file mode 100644
index 0000000..41b6efd
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/variant/pck.ads
@@ -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;
diff --git a/gdb/testsuite/gdb.ada/variant/pkg.adb b/gdb/testsuite/gdb.ada/variant/pkg.adb
new file mode 100644
index 0000000..0cc38f5
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/variant/pkg.adb
@@ -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;