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);
/* 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[] = {
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);
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));
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);
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)
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)
{
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));
}
}
}
- 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;
}
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 *);
\f
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);
{
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)
{
{
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);
}
else
{
fprintf_filtered (stream, "range ");
- print_range_type_named (name, type, stream);
+ print_range_type (type, stream);
}
}
break;