static int discrete_type_p (struct type *);
-static enum ada_renaming_category parse_old_style_renaming (struct type *,
- const char **,
- int *,
- const char **);
-
-static struct symbol *find_old_style_renaming_symbol (const char *,
- const struct block *);
-
static struct type *ada_lookup_struct_elt_type (struct type *, const char *,
int, int);
tagged types. With older versions of GNAT, this type was directly
accessible through a component ("tsd") in the object tag. But this
is no longer the case, so we cache it for each inferior. */
- struct type *tsd_type;
+ struct type *tsd_type = nullptr;
/* The exception_support_info data. This data is used to determine
how to implement support for Ada exception catchpoints in a given
inferior. */
- const struct exception_support_info *exception_info;
+ const struct exception_support_info *exception_info = nullptr;
};
/* Our key to this module's inferior data. */
-static const struct inferior_data *ada_inferior_data;
-
-/* A cleanup routine for our inferior data. */
-static void
-ada_inferior_data_cleanup (struct inferior *inf, void *arg)
-{
- struct ada_inferior_data *data;
-
- data = (struct ada_inferior_data *) inferior_data (inf, ada_inferior_data);
- if (data != NULL)
- xfree (data);
-}
+static const struct inferior_key<ada_inferior_data> ada_inferior_data;
/* Return our inferior data for the given inferior (INF).
{
struct ada_inferior_data *data;
- data = (struct ada_inferior_data *) inferior_data (inf, ada_inferior_data);
+ data = ada_inferior_data.get (inf);
if (data == NULL)
- {
- data = XCNEW (struct ada_inferior_data);
- set_inferior_data (inf, ada_inferior_data, data);
- }
+ data = ada_inferior_data.emplace (inf);
return data;
}
static void
ada_inferior_exit (struct inferior *inf)
{
- ada_inferior_data_cleanup (inf, NULL);
- set_inferior_data (inf, ada_inferior_data, NULL);
+ ada_inferior_data.clear (inf);
}
/* This module's per-program-space data. */
struct ada_pspace_data
{
+ ~ada_pspace_data ()
+ {
+ if (sym_cache != NULL)
+ ada_free_symbol_cache (sym_cache);
+ }
+
/* The Ada symbol cache. */
- struct ada_symbol_cache *sym_cache;
+ struct ada_symbol_cache *sym_cache = nullptr;
};
/* Key to our per-program-space data. */
-static const struct program_space_data *ada_pspace_data_handle;
+static const struct program_space_key<ada_pspace_data> ada_pspace_data_handle;
/* Return this module's data for the given program space (PSPACE).
If not is found, add a zero'ed one now.
{
struct ada_pspace_data *data;
- data = ((struct ada_pspace_data *)
- program_space_data (pspace, ada_pspace_data_handle));
+ data = ada_pspace_data_handle.get (pspace);
if (data == NULL)
- {
- data = XCNEW (struct ada_pspace_data);
- set_program_space_data (pspace, ada_pspace_data_handle, data);
- }
+ data = ada_pspace_data_handle.emplace (pspace);
return data;
}
-/* The cleanup callback for this module's per-program-space data. */
-
-static void
-ada_pspace_data_cleanup (struct program_space *pspace, void *data)
-{
- struct ada_pspace_data *pspace_data = (struct ada_pspace_data *) data;
-
- if (pspace_data->sym_cache != NULL)
- ada_free_symbol_cache (pspace_data->sym_cache);
- xfree (pspace_data);
-}
-
/* Utilities */
/* If TYPE is a TYPE_CODE_TYPEDEF type, return the target type after
set_value_component_location (result, val);
set_value_bitsize (result, value_bitsize (val));
set_value_bitpos (result, value_bitpos (val));
- set_value_address (result, value_address (val));
+ if (VALUE_LVAL (result) == lval_memory)
+ set_value_address (result, value_address (val));
return result;
}
}
enum language
ada_update_initial_language (enum language lang)
{
- if (lookup_minimal_symbol ("adainit", (const char *) NULL,
- (struct objfile *) NULL).minsym != NULL)
+ if (lookup_minimal_symbol ("adainit", NULL, NULL).minsym != NULL)
return language_ada;
return lang;
*len = *len - 1;
}
-/* Remove trailing X[bn]* suffixes (indicating names in package bodies). */
-
-static void
-ada_remove_Xbn_suffix (const char *encoded, int *len)
-{
- int i = *len - 1;
-
- while (i > 0 && (encoded[i] == 'b' || encoded[i] == 'n'))
- i--;
-
- if (encoded[i] != 'X')
- return;
-
- if (i == 0)
- return;
-
- if (isalnum (encoded[i-1]))
- *len = i;
-}
-
/* If ENCODED follows the GNAT entity encoding conventions, then return
the decoded form of ENCODED. Otherwise, return "<%s>" where "%s" is
replaced by ENCODED.
{
default:
return ADA_NOT_RENAMING;
- case LOC_TYPEDEF:
- return parse_old_style_renaming (SYMBOL_TYPE (sym),
- renamed_entity, len, renaming_expr);
case LOC_LOCAL:
case LOC_STATIC:
case LOC_COMPUTED:
return kind;
}
-/* Assuming TYPE encodes a renaming according to the old encoding in
- exp_dbug.ads, returns details of that renaming in *RENAMED_ENTITY,
- *LEN, and *RENAMING_EXPR, as for ada_parse_renaming, above. Returns
- ADA_NOT_RENAMING otherwise. */
-static enum ada_renaming_category
-parse_old_style_renaming (struct type *type,
- const char **renamed_entity, int *len,
- const char **renaming_expr)
-{
- enum ada_renaming_category kind;
- const char *name;
- const char *info;
- const char *suffix;
-
- if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
- || TYPE_NFIELDS (type) != 1)
- return ADA_NOT_RENAMING;
-
- name = TYPE_NAME (type);
- if (name == NULL)
- return ADA_NOT_RENAMING;
-
- name = strstr (name, "___XR");
- if (name == NULL)
- return ADA_NOT_RENAMING;
- switch (name[5])
- {
- case '\0':
- case '_':
- kind = ADA_OBJECT_RENAMING;
- break;
- case 'E':
- kind = ADA_EXCEPTION_RENAMING;
- break;
- case 'P':
- kind = ADA_PACKAGE_RENAMING;
- break;
- case 'S':
- kind = ADA_SUBPROGRAM_RENAMING;
- break;
- default:
- return ADA_NOT_RENAMING;
- }
-
- info = TYPE_FIELD_NAME (type, 0);
- if (info == NULL)
- return ADA_NOT_RENAMING;
- if (renamed_entity != NULL)
- *renamed_entity = info;
- suffix = strstr (info, "___XE");
- if (renaming_expr != NULL)
- *renaming_expr = suffix + 5;
- if (suffix == NULL || suffix == info)
- return ADA_NOT_RENAMING;
- if (len != NULL)
- *len = suffix - info;
- return kind;
-}
-
/* Compute the value of the given RENAMING_SYM, which is expected to
be a symbol encoding a renaming expression. BLOCK is the block
used to evaluate the renaming. */
arg_type = ada_check_typedef (arg_type);
type = TYPE_FIELD_TYPE (arg_type, fieldno);
- /* Handle packed fields. */
-
- if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0)
+ /* Handle packed fields. It might be that the field is not packed
+ relative to its containing structure, but the structure itself is
+ packed; in this case we must take the bit-field path. */
+ if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0 || value_bitpos (arg1) != 0)
{
int bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno);
int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno);
symbols whose name is that of NAME_SYM suffixed with "___XR".
Return symbol if found, and NULL otherwise. */
-struct symbol *
-ada_find_renaming_symbol (struct symbol *name_sym, const struct block *block)
+static bool
+ada_is_renaming_symbol (struct symbol *name_sym)
{
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_type_symbol (name);
- if (sym != NULL && strstr (SYMBOL_LINKAGE_NAME (sym), "___XR") != NULL)
- return sym;
- else
- return NULL;
-}
-
-static struct symbol *
-find_old_style_renaming_symbol (const char *name, const struct block *block)
-{
- const struct symbol *function_sym = block_linkage_function (block);
- char *rename;
-
- if (function_sym != NULL)
- {
- /* If the symbol is defined inside a function, NAME is not fully
- qualified. This means we need to prepend the function name
- as well as adding the ``___XR'' suffix to build the name of
- the associated renaming symbol. */
- const char *function_name = SYMBOL_LINKAGE_NAME (function_sym);
- /* Function names sometimes contain suffixes used
- for instance to qualify nested subprograms. When building
- the XR type name, we need to make sure that this suffix is
- not included. So do not include any suffix in the function
- name length below. */
- int function_name_len = ada_name_prefix_len (function_name);
- const int rename_len = function_name_len + 2 /* "__" */
- + strlen (name) + 6 /* "___XR\0" */ ;
-
- /* Strip the suffix if necessary. */
- ada_remove_trailing_digits (function_name, &function_name_len);
- ada_remove_po_subprogram_suffix (function_name, &function_name_len);
- ada_remove_Xbn_suffix (function_name, &function_name_len);
-
- /* Library-level functions are a special case, as GNAT adds
- a ``_ada_'' prefix to the function name to avoid namespace
- pollution. However, the renaming symbols themselves do not
- have this prefix, so we need to skip this prefix if present. */
- if (function_name_len > 5 /* "_ada_" */
- && strstr (function_name, "_ada_") == function_name)
- {
- function_name += 5;
- function_name_len -= 5;
- }
-
- rename = (char *) alloca (rename_len * sizeof (char));
- strncpy (rename, function_name, function_name_len);
- xsnprintf (rename + function_name_len, rename_len - function_name_len,
- "__%s___XR", name);
- }
- else
- {
- const int rename_len = strlen (name) + 6;
-
- rename = (char *) alloca (rename_len * sizeof (char));
- xsnprintf (rename, rename_len * sizeof (char), "%s___XR", name);
- }
-
- return ada_find_any_type_symbol (rename);
+ return strstr (name, "___XR") != NULL;
}
/* Because of GNAT encoding conventions, several GDB symbols may match a
arg2 = evaluate_subexp (type, exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
- if (ada_is_fixed_point_type (value_type (arg1)))
+ if (VALUE_LVAL (arg1) == lval_internalvar)
+ {
+ /* Nothing. */
+ }
+ else if (ada_is_fixed_point_type (value_type (arg1)))
arg2 = cast_to_fixed (value_type (arg1), arg2);
else if (ada_is_fixed_point_type (value_type (arg2)))
error
because the expression may hold the addresses of multiple symbols
in some cases. */
std::multimap<program_space *, struct bp_location *> loc_map;
- for (struct bp_location *bl = c->loc; bl != NULL; bl = bl->next)
+ for (bp_location *bl = c->loc; bl != NULL; bl = bl->next)
loc_map.emplace (bl->pspace, bl);
scoped_restore_current_program_space save_pspace;
excep_string = ada_encode (excep_string);
std::vector<struct bound_minimal_symbol> symbols
= ada_lookup_simple_minsyms (excep_string);
- for (const struct bound_minimal_symbol &msym : symbols)
+ for (const bound_minimal_symbol &msym : symbols)
{
if (!result.empty ())
result += " or ";
from_tty);
}
+/* Completion function for the Ada "catch" commands. */
+
+static void
+catch_ada_completer (struct cmd_list_element *cmd, completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ std::vector<ada_exc_info> exceptions = ada_exceptions_list (NULL);
+
+ for (const ada_exc_info &info : exceptions)
+ {
+ if (startswith (info.name, word))
+ tracker.add_completion (make_unique_xstrdup (info.name));
+ }
+}
+
/* Split the arguments specified in a "catch assert" command.
ARGS contains the command's arguments (or the empty string if
ada_read_var_value (struct symbol *var, const struct block *var_block,
struct frame_info *frame)
{
- const struct block *frame_block = NULL;
- struct symbol *renaming_sym = NULL;
-
/* The only case where default_read_var_value is not sufficient
is when VAR is a renaming... */
- if (frame)
- frame_block = get_frame_block (frame, NULL);
- if (frame_block)
- renaming_sym = ada_find_renaming_symbol (var, frame_block);
- if (renaming_sym != NULL)
- return ada_read_renaming_var_value (renaming_sym, frame_block);
+ if (frame != nullptr)
+ {
+ const struct block *frame_block = get_frame_block (frame, NULL);
+ if (frame_block != nullptr && ada_is_renaming_symbol (var))
+ return ada_read_renaming_var_value (var, frame_block);
+ }
/* This is a typical case where we expect the default_read_var_value
function to work. */
add_catch_command ("exception", _("\
Catch Ada exceptions, when raised.\n\
-Usage: catch exception [ ARG ]\n\
-\n\
+Usage: catch exception [ARG] [if CONDITION]\n\
Without any argument, stop when any Ada exception is raised.\n\
If ARG is \"unhandled\" (without the quotes), only stop when the exception\n\
being raised does not have a handler (and will therefore lead to the task's\n\
termination).\n\
Otherwise, the catchpoint only stops when the name of the exception being\n\
-raised is the same as ARG."),
+raised is the same as ARG.\n\
+CONDITION is a boolean expression that is evaluated to see whether the\n\
+exception should cause a stop."),
catch_ada_exception_command,
- NULL,
+ catch_ada_completer,
CATCH_PERMANENT,
CATCH_TEMPORARY);
add_catch_command ("handlers", _("\
Catch Ada exceptions, when handled.\n\
-With an argument, catch only exceptions with the given name."),
+Usage: catch handlers [ARG] [if CONDITION]\n\
+Without any argument, stop when any Ada exception is handled.\n\
+With an argument, catch only exceptions with the given name.\n\
+CONDITION is a boolean expression that is evaluated to see whether the\n\
+exception should cause a stop."),
catch_ada_handlers_command,
- NULL,
+ catch_ada_completer,
CATCH_PERMANENT,
CATCH_TEMPORARY);
add_catch_command ("assert", _("\
Catch failed Ada assertions, when raised.\n\
-With an argument, catch only exceptions with the given name."),
+Usage: catch assert [if CONDITION]\n\
+CONDITION is a boolean expression that is evaluated to see whether the\n\
+exception should cause a stop."),
catch_assert_command,
NULL,
CATCH_PERMANENT,
add_info ("exceptions", info_exceptions_command,
_("\
List all Ada exception names.\n\
+Usage: info exceptions [REGEXP]\n\
If a regular expression is passed as an argument, only those matching\n\
the regular expression are listed."));
gdb::observers::new_objfile.attach (ada_new_objfile_observer);
gdb::observers::free_objfile.attach (ada_free_objfile_observer);
gdb::observers::inferior_exit.attach (ada_inferior_exit);
-
- /* Setup various context-specific data. */
- ada_inferior_data
- = register_inferior_data_with_cleanup (NULL, ada_inferior_data_cleanup);
- ada_pspace_data_handle
- = register_program_space_data_with_cleanup (NULL, ada_pspace_data_cleanup);
}