Avoid global lookup when decoding XA type.

This patch enhances GDB to take advantage of a recent change in the GNAT
encoding regarding XA types.  A detailed description of the logic has
been added at the start of ada_fixup_array_indexes_type to give the
context behind this enhancement.

2010-05-17  Joel Brobecker  <brobecker@adacore.com>

        * ada-lang.c (to_fixed_range_type): The the raw index type as
        argument instead of the raw type name.  Remove orig_type parameter.
        Update calls throughout.
        (ada_fixup_array_indexes_type): New function.
        (ada_array_bound_from_type): Add call to ada_fixup_array_indexes_type.
        * ada-lang.h (ada_fixup_array_indexes_type): Add declaration.
        * ada-typeprint.c (print_range_type): Renames print_range_type_named.
        Remove name parameter.
        (print_array_type): Add call to ada_fixup_array_indexes_type.
        Update calls to print_range_type.
        (ada_print_type): Update calls to print_range_type.
This commit is contained in:
Joel Brobecker 2010-05-17 16:55:31 +00:00
parent 3872d37d18
commit 28c85d6c4b
4 changed files with 100 additions and 28 deletions

View File

@ -4,6 +4,20 @@
* c-lang.c (c_printstr): Compute real length of NUL terminated
string at first.
2010-05-17 Joel Brobecker <brobecker@adacore.com>
* ada-lang.c (to_fixed_range_type): The the raw index type as
argument instead of the raw type name. Remove orig_type parameter.
Update calls throughout.
(ada_fixup_array_indexes_type): New function.
(ada_array_bound_from_type): Add call to ada_fixup_array_indexes_type.
* ada-lang.h (ada_fixup_array_indexes_type): Add declaration.
* ada-typeprint.c (print_range_type): Renames print_range_type_named.
Remove name parameter.
(print_array_type): Add call to ada_fixup_array_indexes_type.
Update calls to print_range_type.
(ada_print_type): Update calls to print_range_type.
2010-05-17 Pierre Muller <muller@ics.u-strasbg.fr>
* dwarf2read.c (read_set_type): Set type length if

View File

@ -165,8 +165,7 @@ static struct type *to_fixed_variant_branch_type (struct type *,
static struct type *to_fixed_array_type (struct type *, struct value *, int);
static struct type *to_fixed_range_type (char *, struct value *,
struct type *);
static struct type *to_fixed_range_type (struct type *, struct value *);
static struct type *to_static_fixed_type (struct type *);
static struct type *static_unwrap_type (struct type *type);
@ -1204,6 +1203,61 @@ ada_match_name (const char *sym_name, const char *name, int wild)
/* Arrays */
/* Assuming that INDEX_DESC_TYPE is an ___XA structure, a structure
generated by the GNAT compiler to describe the index type used
for each dimension of an array, check whether it follows the latest
known encoding. If not, fix it up to conform to the latest encoding.
Otherwise, do nothing. This function also does nothing if
INDEX_DESC_TYPE is NULL.
The GNAT encoding used to describle the array index type evolved a bit.
Initially, the information would be provided through the name of each
field of the structure type only, while the type of these fields was
described as unspecified and irrelevant. The debugger was then expected
to perform a global type lookup using the name of that field in order
to get access to the full index type description. Because these global
lookups can be very expensive, the encoding was later enhanced to make
the global lookup unnecessary by defining the field type as being
the full index type description.
The purpose of this routine is to allow us to support older versions
of the compiler by detecting the use of the older encoding, and by
fixing up the INDEX_DESC_TYPE to follow the new one (at this point,
we essentially replace each field's meaningless type by the associated
index subtype). */
void
ada_fixup_array_indexes_type (struct type *index_desc_type)
{
int i;
if (index_desc_type == NULL)
return;
gdb_assert (TYPE_NFIELDS (index_desc_type) > 0);
/* Check if INDEX_DESC_TYPE follows the older encoding (it is sufficient
to check one field only, no need to check them all). If not, return
now.
If our INDEX_DESC_TYPE was generated using the older encoding,
the field type should be a meaningless integer type whose name
is not equal to the field name. */
if (TYPE_NAME (TYPE_FIELD_TYPE (index_desc_type, 0)) != NULL
&& strcmp (TYPE_NAME (TYPE_FIELD_TYPE (index_desc_type, 0)),
TYPE_FIELD_NAME (index_desc_type, 0)) == 0)
return;
/* Fixup each field of INDEX_DESC_TYPE. */
for (i = 0; i < TYPE_NFIELDS (index_desc_type); i++)
{
char *name = TYPE_FIELD_NAME (index_desc_type, i);
struct type *raw_type = ada_check_typedef (ada_find_any_type (name));
if (raw_type)
TYPE_FIELD_TYPE (index_desc_type, i) = raw_type;
}
}
/* Names of MAX_ADA_DIMENS bounds in P_BOUNDS fields of array descriptors. */
static char *bound_name[] = {
@ -2530,9 +2584,10 @@ ada_array_bound_from_type (struct type * arr_type, int n, int which)
elt_type = TYPE_TARGET_TYPE (type);
index_type_desc = ada_find_parallel_type (type, "___XA");
ada_fixup_array_indexes_type (index_type_desc);
if (index_type_desc != NULL)
index_type = to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, n - 1),
NULL, TYPE_INDEX_TYPE (elt_type));
index_type = to_fixed_range_type (TYPE_FIELD_TYPE (index_type_desc, n - 1),
NULL);
else
index_type = TYPE_INDEX_TYPE (elt_type);
@ -7150,6 +7205,7 @@ to_fixed_array_type (struct type *type0, struct value *dval,
type0 = decode_constrained_packed_array_type (type0);
index_type_desc = ada_find_parallel_type (type0, "___XA");
ada_fixup_array_indexes_type (index_type_desc);
if (index_type_desc == NULL)
{
struct type *elt_type0 = ada_check_typedef (TYPE_TARGET_TYPE (type0));
@ -7202,8 +7258,7 @@ to_fixed_array_type (struct type *type0, struct value *dval,
for (i = TYPE_NFIELDS (index_type_desc) - 1; i >= 0; i -= 1)
{
struct type *range_type =
to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, i),
dval, TYPE_INDEX_TYPE (elt_type0));
to_fixed_range_type (TYPE_FIELD_TYPE (index_type_desc, i), dval);
result = create_array_type (alloc_type_copy (elt_type0),
result, range_type);
elt_type0 = TYPE_TARGET_TYPE (elt_type0);
@ -9182,7 +9237,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
char *name = ada_type_name (type_arg);
range_type = NULL;
if (name != NULL && TYPE_CODE (type_arg) != TYPE_CODE_ENUM)
range_type = to_fixed_range_type (name, NULL, type_arg);
range_type = to_fixed_range_type (type_arg, NULL);
if (range_type == NULL)
range_type = type_arg;
switch (op)
@ -9704,21 +9759,21 @@ get_int_var_value (char *name, int *flag)
in NAME, the base type given in the named range type. */
static struct type *
to_fixed_range_type (char *name, struct value *dval, struct type *orig_type)
to_fixed_range_type (struct type *raw_type, struct value *dval)
{
struct type *raw_type = ada_find_any_type (name);
char *name;
struct type *base_type;
char *subtype_info;
/* Fall back to the original type if symbol lookup failed. */
if (raw_type == NULL)
raw_type = orig_type;
gdb_assert (raw_type != NULL);
gdb_assert (TYPE_NAME (raw_type) != NULL);
if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE)
base_type = TYPE_TARGET_TYPE (raw_type);
else
base_type = raw_type;
name = TYPE_NAME (raw_type);
subtype_info = strstr (name, "___XD");
if (subtype_info == NULL)
{
@ -9727,7 +9782,7 @@ to_fixed_range_type (char *name, struct value *dval, struct type *orig_type)
if (L < INT_MIN || U > INT_MAX)
return raw_type;
else
return create_range_type (alloc_type_copy (orig_type), raw_type,
return create_range_type (alloc_type_copy (raw_type), raw_type,
ada_discrete_type_low_bound (raw_type),
ada_discrete_type_high_bound (raw_type));
}
@ -9790,7 +9845,7 @@ to_fixed_range_type (char *name, struct value *dval, struct type *orig_type)
}
}
type = create_range_type (alloc_type_copy (orig_type), base_type, L, U);
type = create_range_type (alloc_type_copy (raw_type), base_type, L, U);
TYPE_NAME (type) = name;
return type;
}

View File

@ -187,6 +187,8 @@ struct value *ada_convert_actual (struct value *actual,
extern struct value *ada_value_subscript (struct value *, int,
struct value **);
extern void ada_fixup_array_indexes_type (struct type *index_desc_type);
extern struct type *ada_array_element_type (struct type *, int);
extern int ada_array_arity (struct type *);

View File

@ -55,7 +55,7 @@ static void
print_dynamic_range_bound (struct type *, const char *, int,
const char *, struct ui_file *);
static void print_range_type_named (char *, struct type *, struct ui_file *);
static void print_range_type (struct type *, struct ui_file *);
@ -212,19 +212,19 @@ print_dynamic_range_bound (struct type *type, const char *name, int name_len,
fprintf_filtered (stream, "?");
}
/* Print the range type named NAME. If symbol lookup fails, fall back
to ORIG_TYPE as base type. */
/* Print RAW_TYPE as a range type, using any bound information
following the GNAT encoding (if available). */
static void
print_range_type_named (char *name, struct type *orig_type,
struct ui_file *stream)
print_range_type (struct type *raw_type, struct ui_file *stream)
{
struct type *raw_type = ada_find_any_type (name);
char *name;
struct type *base_type;
char *subtype_info;
if (raw_type == NULL)
raw_type = orig_type;
gdb_assert (raw_type != NULL);
name = TYPE_NAME (raw_type);
gdb_assert (name != NULL);
if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE)
base_type = TYPE_TARGET_TYPE (raw_type);
@ -341,10 +341,12 @@ print_array_type (struct type *type, struct ui_file *stream, int show,
{
if (ada_is_simple_array_type (type))
{
struct type *range_desc_type =
ada_find_parallel_type (type, "___XA");
struct type *range_desc_type;
struct type *arr_type;
range_desc_type = ada_find_parallel_type (type, "___XA");
ada_fixup_array_indexes_type (range_desc_type);
bitsize = 0;
if (range_desc_type == NULL)
{
@ -368,9 +370,8 @@ print_array_type (struct type *type, struct ui_file *stream, int show,
{
if (k > 0)
fprintf_filtered (stream, ", ");
print_range_type_named (TYPE_FIELD_NAME
(range_desc_type, k),
TYPE_INDEX_TYPE (arr_type), stream);
print_range_type (TYPE_FIELD_TYPE (range_desc_type, k),
stream);
if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
}
@ -786,7 +787,7 @@ ada_print_type (struct type *type0, char *varstring, struct ui_file *stream,
else
{
fprintf_filtered (stream, "range ");
print_range_type_named (name, type, stream);
print_range_type (type, stream);
}
}
break;