static void ada_forward_operator_length (struct expression *, int, int *,
int *);
+
+static struct type *ada_find_any_type (const char *name);
\f
}
return type;
}
+
+/* Return a decoded version of the given VALUE. This means returning
+ a value whose type is obtained by applying all the GNAT-specific
+ encondings, making the resulting type a static but standard description
+ of the initial type. */
+
+struct value *
+ada_get_decoded_value (struct value *value)
+{
+ struct type *type = ada_check_typedef (value_type (value));
+
+ if (ada_is_array_descriptor_type (type)
+ || (ada_is_constrained_packed_array_type (type)
+ && TYPE_CODE (type) != TYPE_CODE_PTR))
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) /* array access type. */
+ value = ada_coerce_to_simple_array_ptr (value);
+ else
+ value = ada_coerce_to_simple_array (value);
+ }
+ else
+ value = ada_to_fixed_value (value);
+
+ return value;
+}
+
+/* Same as ada_get_decoded_value, but with the given TYPE.
+ Because there is no associated actual value for this type,
+ the resulting type might be a best-effort approximation in
+ the case of dynamic types. */
+
+struct type *
+ada_get_decoded_type (struct type *type)
+{
+ type = to_static_fixed_type (type);
+ if (ada_is_constrained_packed_array_type (type))
+ type = ada_coerce_to_simple_array_type (type);
+ return type;
+}
+
\f
/* Language Selection */
return NULL;
}
-struct tag_args
+/* Return the "ada__tags__type_specific_data" type. */
+
+static struct type *
+ada_get_tsd_type (struct inferior *inf)
{
- struct value *tag;
- char *name;
-};
+ struct ada_inferior_data *data = get_ada_inferior_data (inf);
+ if (data->tsd_type == 0)
+ data->tsd_type = ada_find_any_type ("ada__tags__type_specific_data");
+ return data->tsd_type;
+}
-static int ada_tag_name_1 (void *);
-static int ada_tag_name_2 (struct tag_args *);
+/* Return the TSD (type-specific data) associated to the given TAG.
+ TAG is assumed to be the tag of a tagged-type entity.
-/* Wrapper function used by ada_tag_name. Given a struct tag_args*
- value ARGS, sets ARGS->name to the tag name of ARGS->tag.
- The value stored in ARGS->name is valid until the next call to
- ada_tag_name_1. */
+ May return NULL if we are unable to get the TSD. */
-static int
-ada_tag_name_1 (void *args0)
+static struct value *
+ada_get_tsd_from_tag (struct value *tag)
{
- struct tag_args *args = (struct tag_args *) args0;
- static char name[1024];
- char *p;
struct value *val;
+ struct type *type;
- args->name = NULL;
- val = ada_value_struct_elt (args->tag, "tsd", 1);
- if (val == NULL)
- return ada_tag_name_2 (args);
- val = ada_value_struct_elt (val, "expanded_name", 1);
- if (val == NULL)
- return 0;
- read_memory_string (value_as_address (val), name, sizeof (name) - 1);
- for (p = name; *p != '\0'; p += 1)
- if (isalpha (*p))
- *p = tolower (*p);
- args->name = name;
- return 0;
-}
+ /* First option: The TSD is simply stored as a field of our TAG.
+ Only older versions of GNAT would use this format, but we have
+ to test it first, because there are no visible markers for
+ the current approach except the absence of that field. */
-/* Return the "ada__tags__type_specific_data" type. */
+ val = ada_value_struct_elt (tag, "tsd", 1);
+ if (val)
+ return val;
-static struct type *
-ada_get_tsd_type (struct inferior *inf)
-{
- struct ada_inferior_data *data = get_ada_inferior_data (inf);
+ /* Try the second representation for the dispatch table (in which
+ there is no explicit 'tsd' field in the referent of the tag pointer,
+ and instead the tsd pointer is stored just before the dispatch
+ table. */
- if (data->tsd_type == 0)
- data->tsd_type = ada_find_any_type ("ada__tags__type_specific_data");
- return data->tsd_type;
+ type = ada_get_tsd_type (current_inferior());
+ if (type == NULL)
+ return NULL;
+ type = lookup_pointer_type (lookup_pointer_type (type));
+ val = value_cast (type, tag);
+ if (val == NULL)
+ return NULL;
+ return value_ind (value_ptradd (val, -1));
}
-/* Utility function for ada_tag_name_1 that tries the second
- representation for the dispatch table (in which there is no
- explicit 'tsd' field in the referent of the tag pointer, and instead
- the tsd pointer is stored just before the dispatch table. */
-
-static int
-ada_tag_name_2 (struct tag_args *args)
+/* Given the TSD of a tag (type-specific data), return a string
+ containing the name of the associated type.
+
+ The returned value is good until the next call. May return NULL
+ if we are unable to determine the tag name. */
+
+static char *
+ada_tag_name_from_tsd (struct value *tsd)
{
- struct type *info_type;
static char name[1024];
char *p;
- struct value *val, *valp;
+ struct value *val;
- args->name = NULL;
- info_type = ada_get_tsd_type (current_inferior());
- if (info_type == NULL)
- return 0;
- info_type = lookup_pointer_type (lookup_pointer_type (info_type));
- valp = value_cast (info_type, args->tag);
- if (valp == NULL)
- return 0;
- val = value_ind (value_ptradd (valp, -1));
+ val = ada_value_struct_elt (tsd, "expanded_name", 1);
if (val == NULL)
- return 0;
- val = ada_value_struct_elt (val, "expanded_name", 1);
- if (val == NULL)
- return 0;
+ return NULL;
read_memory_string (value_as_address (val), name, sizeof (name) - 1);
for (p = name; *p != '\0'; p += 1)
if (isalpha (*p))
*p = tolower (*p);
- args->name = name;
- return 0;
+ return name;
}
/* The type name of the dynamic type denoted by the 'tag value TAG, as
- a C string. */
+ a C string.
+
+ Return NULL if the TAG is not an Ada tag, or if we were unable to
+ determine the name of that tag. The result is good until the next
+ call. */
const char *
ada_tag_name (struct value *tag)
{
- struct tag_args args;
+ volatile struct gdb_exception e;
+ char *name = NULL;
if (!ada_is_tag_type (value_type (tag)))
return NULL;
- args.tag = tag;
- args.name = NULL;
- catch_errors (ada_tag_name_1, &args, NULL, RETURN_MASK_ALL);
- return args.name;
+
+ /* It is perfectly possible that an exception be raised while trying
+ to determine the TAG's name, even under normal circumstances:
+ The associated variable may be uninitialized or corrupted, for
+ instance. We do not let any exception propagate past this point.
+ instead we return NULL.
+
+ We also do not print the error message either (which often is very
+ low-level (Eg: "Cannot read memory at 0x[...]"), but instead let
+ the caller print a more meaningful message if necessary. */
+ TRY_CATCH (e, RETURN_MASK_ERROR)
+ {
+ struct value *tsd = ada_get_tsd_from_tag (tag);
+
+ if (tsd != NULL)
+ name = ada_tag_name_from_tsd (tsd);
+ }
+
+ return name;
}
/* The parent type of TYPE, or NULL if none. */
return atoi (name + align_offset) * TARGET_CHAR_BIT;
}
-/* Find a symbol named NAME. Ignores ambiguity. */
+/* Find a typedef or tag symbol named NAME. Ignores ambiguity. */
-struct symbol *
-ada_find_any_symbol (const char *name)
+static struct symbol *
+ada_find_any_type_symbol (const char *name)
{
struct symbol *sym;
solely for types defined by debug info, it will not search the GDB
primitive types. */
-struct type *
+static struct type *
ada_find_any_type (const char *name)
{
- struct symbol *sym = ada_find_any_symbol (name);
+ struct symbol *sym = ada_find_any_type_symbol (name);
if (sym != NULL)
return SYMBOL_TYPE (sym);
return NULL;
}
-/* Given NAME and an associated BLOCK, search all symbols for
- NAME suffixed with "___XR", which is the ``renaming'' symbol
- associated to NAME. Return this symbol if found, return
- NULL otherwise. */
+/* Given NAME_SYM and an associated BLOCK, find a "renaming" symbol
+ associated with NAME_SYM's name. NAME_SYM may itself be a renaming
+ symbol, in which case it is returned. Otherwise, this looks for
+ symbols whose name is that of NAME_SYM suffixed with "___XR".
+ Return symbol if found, and NULL otherwise. */
struct symbol *
-ada_find_renaming_symbol (const char *name, struct block *block)
+ada_find_renaming_symbol (struct symbol *name_sym, struct block *block)
{
+ const char *name = SYMBOL_LINKAGE_NAME (name_sym);
struct symbol *sym;
+ if (strstr (name, "___XR") != NULL)
+ return name_sym;
+
sym = find_old_style_renaming_symbol (name, block);
if (sym != NULL)
return sym;
/* Not right yet. FIXME pnh 7/20/2007. */
- sym = ada_find_any_symbol (name);
+ sym = ada_find_any_type_symbol (name);
if (sym != NULL && strstr (SYMBOL_LINKAGE_NAME (sym), "___XR") != NULL)
return sym;
else
xsnprintf (rename, rename_len * sizeof (char), "%s___XR", name);
}
- return ada_find_any_symbol (rename);
+ return ada_find_any_type_symbol (rename);
}
/* Because of GNAT encoding conventions, several GDB symbols may match a
&& TYPE_UNSIGNED (subranged_type));
}
-/* Try to determine the lower and upper bounds of the given modular type
- using the type name only. Return non-zero and set L and U as the lower
- and upper bounds (respectively) if successful. */
-
-int
-ada_modulus_from_name (struct type *type, ULONGEST *modulus)
-{
- const char *name = ada_type_name (type);
- const char *suffix;
- int k;
- LONGEST U;
-
- if (name == NULL)
- return 0;
-
- /* Discrete type bounds are encoded using an __XD suffix. In our case,
- we are looking for static bounds, which means an __XDLU suffix.
- Moreover, we know that the lower bound of modular types is always
- zero, so the actual suffix should start with "__XDLU_0__", and
- then be followed by the upper bound value. */
- suffix = strstr (name, "__XDLU_0__");
- if (suffix == NULL)
- return 0;
- k = 10;
- if (!ada_scan_number (suffix, k, &U, NULL))
- return 0;
-
- *modulus = (ULONGEST) U + 1;
- return 1;
-}
-
/* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */
ULONGEST