static struct value *
thin_data_pntr (struct value *val)
{
- struct type *type = value_type (val);
+ struct type *type = ada_check_typedef (value_type (val));
struct type *data_type = desc_data_target_type (thin_descriptor_type (type));
data_type = lookup_pointer_type (data_type);
of the routine assumes that the array hasn't been decoded yet,
so we use the basic "value_ind" routine to perform the dereferencing,
as opposed to using "ada_value_ind". */
- if (TYPE_CODE (value_type (arr)) == TYPE_CODE_PTR)
+ if (TYPE_CODE (ada_check_typedef (value_type (arr))) == TYPE_CODE_PTR)
arr = value_ind (arr);
type = decode_constrained_packed_array_type (value_type (arr));
return (name != NULL && strcmp (name, "<variable, no debug info>") == 0);
}
+/* Return nonzero if TYPE1 and TYPE2 are two enumeration types
+ that are deemed "identical" for practical purposes.
+
+ This function assumes that TYPE1 and TYPE2 are both TYPE_CODE_ENUM
+ types and that their number of enumerals is identical (in other
+ words, TYPE_NFIELDS (type1) == TYPE_NFIELDS (type2)). */
+
+static int
+ada_identical_enum_types_p (struct type *type1, struct type *type2)
+{
+ int i;
+
+ /* The heuristic we use here is fairly conservative. We consider
+ that 2 enumerate types are identical if they have the same
+ number of enumerals and that all enumerals have the same
+ underlying value and name. */
+
+ /* All enums in the type should have an identical underlying value. */
+ for (i = 0; i < TYPE_NFIELDS (type1); i++)
+ if (TYPE_FIELD_BITPOS (type1, i) != TYPE_FIELD_BITPOS (type2, i))
+ return 0;
+
+ /* All enumerals should also have the same name (modulo any numerical
+ suffix). */
+ for (i = 0; i < TYPE_NFIELDS (type1); i++)
+ {
+ char *name_1 = TYPE_FIELD_NAME (type1, i);
+ char *name_2 = TYPE_FIELD_NAME (type2, i);
+ int len_1 = strlen (name_1);
+ int len_2 = strlen (name_2);
+
+ ada_remove_trailing_digits (TYPE_FIELD_NAME (type1, i), &len_1);
+ ada_remove_trailing_digits (TYPE_FIELD_NAME (type2, i), &len_2);
+ if (len_1 != len_2
+ || strncmp (TYPE_FIELD_NAME (type1, i),
+ TYPE_FIELD_NAME (type2, i),
+ len_1) != 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Return nonzero if all the symbols in SYMS are all enumeral symbols
+ that are deemed "identical" for practical purposes. Sometimes,
+ enumerals are not strictly identical, but their types are so similar
+ that they can be considered identical.
+
+ For instance, consider the following code:
+
+ type Color is (Black, Red, Green, Blue, White);
+ type RGB_Color is new Color range Red .. Blue;
+
+ Type RGB_Color is a subrange of an implicit type which is a copy
+ of type Color. If we call that implicit type RGB_ColorB ("B" is
+ for "Base Type"), then type RGB_ColorB is a copy of type Color.
+ As a result, when an expression references any of the enumeral
+ by name (Eg. "print green"), the expression is technically
+ ambiguous and the user should be asked to disambiguate. But
+ doing so would only hinder the user, since it wouldn't matter
+ what choice he makes, the outcome would always be the same.
+ So, for practical purposes, we consider them as the same. */
+
+static int
+symbols_are_identical_enums (struct ada_symbol_info *syms, int nsyms)
+{
+ int i;
+
+ /* Before performing a thorough comparison check of each type,
+ we perform a series of inexpensive checks. We expect that these
+ checks will quickly fail in the vast majority of cases, and thus
+ help prevent the unnecessary use of a more expensive comparison.
+ Said comparison also expects us to make some of these checks
+ (see ada_identical_enum_types_p). */
+
+ /* Quick check: All symbols should have an enum type. */
+ for (i = 0; i < nsyms; i++)
+ if (TYPE_CODE (SYMBOL_TYPE (syms[i].sym)) != TYPE_CODE_ENUM)
+ return 0;
+
+ /* Quick check: They should all have the same value. */
+ for (i = 1; i < nsyms; i++)
+ if (SYMBOL_VALUE (syms[i].sym) != SYMBOL_VALUE (syms[0].sym))
+ return 0;
+
+ /* Quick check: They should all have the same number of enumerals. */
+ for (i = 1; i < nsyms; i++)
+ if (TYPE_NFIELDS (SYMBOL_TYPE (syms[i].sym))
+ != TYPE_NFIELDS (SYMBOL_TYPE (syms[0].sym)))
+ return 0;
+
+ /* All the sanity checks passed, so we might have a set of
+ identical enumeration types. Perform a more complete
+ comparison of the type of each symbol. */
+ for (i = 1; i < nsyms; i++)
+ if (!ada_identical_enum_types_p (SYMBOL_TYPE (syms[i].sym),
+ SYMBOL_TYPE (syms[0].sym)))
+ return 0;
+
+ return 1;
+}
+
/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely
duplicate other symbols in the list (The only case I know of where
this happens is when object files containing stabs-in-ecoff are
{
int i, j;
+ /* We should never be called with less than 2 symbols, as there
+ cannot be any extra symbol in that case. But it's easy to
+ handle, since we have nothing to do in that case. */
+ if (nsyms < 2)
+ return nsyms;
+
i = 0;
while (i < nsyms)
{
i += 1;
}
+
+ /* If all the remaining symbols are identical enumerals, then
+ just keep the first one and discard the rest.
+
+ Unlike what we did previously, we do not discard any entry
+ unless they are ALL identical. This is because the symbol
+ comparison is not a strict comparison, but rather a practical
+ comparison. If all symbols are considered identical, then
+ we can just go ahead and use the first one and discard the rest.
+ But if we cannot reduce the list to a single element, we have
+ to ask the user to disambiguate anyways. And if we have to
+ present a multiple-choice menu, it's less confusing if the list
+ isn't missing some choices that were identical and yet distinct. */
+ if (symbols_are_identical_enums (syms, nsyms))
+ nsyms = 1;
+
return nsyms;
}
/* First, unqualify the enumeration name:
1. Search for the last '.' character. If we find one, then skip
- all the preceeding characters, the unqualified name starts
+ all the preceding characters, the unqualified name starts
right after that dot.
2. Otherwise, we may be debugging on a target where the compiler
translates dots into "__". Search forward for double underscores,
type = ada_check_typedef (value_type (argvec[0]));
/* Ada allows us to implicitly dereference arrays when subscripting
- them. So, if this is an typedef (encoding use for array access
- types encoded as fat pointers), strip it now. */
+ them. So, if this is an array typedef (encoding use for array
+ access types encoded as fat pointers), strip it now. */
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
type = ada_typedef_target_type (type);
if (!ada_is_simple_array_type (value_type (array)))
error (_("cannot take slice of non-array"));
- if (TYPE_CODE (value_type (array)) == TYPE_CODE_PTR)
+ if (TYPE_CODE (ada_check_typedef (value_type (array)))
+ == TYPE_CODE_PTR)
{
+ struct type *type0 = ada_check_typedef (value_type (array));
+
if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS)
- return empty_array (TYPE_TARGET_TYPE (value_type (array)),
- low_bound);
+ return empty_array (TYPE_TARGET_TYPE (type0), low_bound);
else
{
struct type *arr_type0 =
- to_fixed_array_type (TYPE_TARGET_TYPE (value_type (array)),
- NULL, 1);
+ to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1);
return ada_value_slice_from_ptr (array, arr_type0,
longest_to_int (low_bound),
static struct symtab_and_line ada_exception_sal (enum exception_catchpoint_kind,
char *, char **,
- struct breakpoint_ops **);
+ const struct breakpoint_ops **);
static char *ada_exception_catchpoint_cond_string (const char *excep_string);
/* Ada catchpoints.
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
xfree (c->excep_string);
+
+ bkpt_breakpoint_ops.dtor (b);
}
/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
/* Call the base class's method. This updates the catchpoint's
locations. */
- breakpoint_re_set_default (b);
+ bkpt_breakpoint_ops.re_set (b);
/* Reparse the exception conditional expressions. One for each
location. */
for all exception catchpoint kinds. */
static enum print_stop_action
-print_it_exception (enum exception_catchpoint_kind ex, struct breakpoint *b)
+print_it_exception (enum exception_catchpoint_kind ex, bpstat bs)
{
+ struct ui_out *uiout = current_uiout;
+ struct breakpoint *b = bs->breakpoint_at;
+
annotate_catchpoint (b->number);
if (ui_out_is_mi_like_p (uiout))
ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
}
- ui_out_text (uiout, "\nCatchpoint ");
+ ui_out_text (uiout,
+ b->disposition == disp_del ? "\nTemporary catchpoint "
+ : "\nCatchpoint ");
ui_out_field_int (uiout, "bkptno", b->number);
ui_out_text (uiout, ", ");
print_one_exception (enum exception_catchpoint_kind ex,
struct breakpoint *b, struct bp_location **last_loc)
{
+ struct ui_out *uiout = current_uiout;
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
struct value_print_options opts;
struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+ struct ui_out *uiout = current_uiout;
+
+ ui_out_text (uiout, b->disposition == disp_del ? _("Temporary catchpoint ")
+ : _("Catchpoint "));
+ ui_out_field_int (uiout, "bkptno", b->number);
+ ui_out_text (uiout, ": ");
switch (ex)
{
case ex_catch_exception:
if (c->excep_string != NULL)
- printf_filtered (_("Catchpoint %d: `%s' Ada exception"),
- b->number, c->excep_string);
+ {
+ char *info = xstrprintf (_("`%s' Ada exception"), c->excep_string);
+ struct cleanup *old_chain = make_cleanup (xfree, info);
+
+ ui_out_text (uiout, info);
+ do_cleanups (old_chain);
+ }
else
- printf_filtered (_("Catchpoint %d: all Ada exceptions"), b->number);
-
+ ui_out_text (uiout, _("all Ada exceptions"));
break;
case ex_catch_exception_unhandled:
- printf_filtered (_("Catchpoint %d: unhandled Ada exceptions"),
- b->number);
+ ui_out_text (uiout, _("unhandled Ada exceptions"));
break;
case ex_catch_assert:
- printf_filtered (_("Catchpoint %d: failed Ada assertions"), b->number);
+ ui_out_text (uiout, _("failed Ada assertions"));
break;
default:
default:
internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
}
+ print_recreate_thread (b, fp);
}
/* Virtual table for "catch exception" breakpoints. */
}
static enum print_stop_action
-print_it_catch_exception (struct breakpoint *b)
+print_it_catch_exception (bpstat bs)
{
- return print_it_exception (ex_catch_exception, b);
+ return print_it_exception (ex_catch_exception, bs);
}
static void
print_recreate_exception (ex_catch_exception, b, fp);
}
-static struct breakpoint_ops catch_exception_breakpoint_ops =
-{
- dtor_catch_exception,
- allocate_location_catch_exception,
- re_set_catch_exception,
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
- check_status_catch_exception,
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
- print_it_catch_exception,
- print_one_catch_exception,
- NULL, /* print_one_detail */
- print_mention_catch_exception,
- print_recreate_catch_exception
-};
+static struct breakpoint_ops catch_exception_breakpoint_ops;
/* Virtual table for "catch exception unhandled" breakpoints. */
}
static enum print_stop_action
-print_it_catch_exception_unhandled (struct breakpoint *b)
+print_it_catch_exception_unhandled (bpstat bs)
{
- return print_it_exception (ex_catch_exception_unhandled, b);
+ return print_it_exception (ex_catch_exception_unhandled, bs);
}
static void
print_recreate_exception (ex_catch_exception_unhandled, b, fp);
}
-static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
- dtor_catch_exception_unhandled,
- allocate_location_catch_exception_unhandled,
- re_set_catch_exception_unhandled,
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
- check_status_catch_exception_unhandled,
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
- print_it_catch_exception_unhandled,
- print_one_catch_exception_unhandled,
- NULL, /* print_one_detail */
- print_mention_catch_exception_unhandled,
- print_recreate_catch_exception_unhandled
-};
+static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops;
/* Virtual table for "catch assert" breakpoints. */
}
static enum print_stop_action
-print_it_catch_assert (struct breakpoint *b)
+print_it_catch_assert (bpstat bs)
{
- return print_it_exception (ex_catch_assert, b);
+ return print_it_exception (ex_catch_assert, bs);
}
static void
print_recreate_exception (ex_catch_assert, b, fp);
}
-static struct breakpoint_ops catch_assert_breakpoint_ops = {
- dtor_catch_assert,
- allocate_location_catch_assert,
- re_set_catch_assert,
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
- check_status_catch_assert,
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
- print_it_catch_assert,
- print_one_catch_assert,
- NULL, /* print_one_detail */
- print_mention_catch_assert,
- print_recreate_catch_assert
-};
+static struct breakpoint_ops catch_assert_breakpoint_ops;
/* Return a newly allocated copy of the first space-separated token
in ARGSP, and then adjust ARGSP to point immediately after that
/* Return the breakpoint ops "virtual table" used for catchpoints
of the EX kind. */
-static struct breakpoint_ops *
+static const struct breakpoint_ops *
ada_exception_breakpoint_ops (enum exception_catchpoint_kind ex)
{
switch (ex)
static struct symtab_and_line
ada_exception_sal (enum exception_catchpoint_kind ex, char *excep_string,
- char **addr_string, struct breakpoint_ops **ops)
+ char **addr_string, const struct breakpoint_ops **ops)
{
const char *sym_name;
struct symbol *sym;
static struct symtab_and_line
ada_decode_exception_location (char *args, char **addr_string,
char **excep_string,
- struct breakpoint_ops **ops)
+ const struct breakpoint_ops **ops)
{
enum exception_catchpoint_kind ex;
struct symtab_and_line sal,
char *addr_string,
char *excep_string,
- struct breakpoint_ops *ops,
+ const struct breakpoint_ops *ops,
int tempflag,
int from_tty)
{
ops, tempflag, from_tty);
c->excep_string = excep_string;
create_excep_cond_exprs (c);
- install_breakpoint (&c->base);
+ install_breakpoint (0, &c->base);
}
/* Implement the "catch exception" command. */
struct symtab_and_line sal;
char *addr_string = NULL;
char *excep_string = NULL;
- struct breakpoint_ops *ops = NULL;
+ const struct breakpoint_ops *ops = NULL;
tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
static struct symtab_and_line
ada_decode_assert_location (char *args, char **addr_string,
- struct breakpoint_ops **ops)
+ const struct breakpoint_ops **ops)
{
/* Check that no argument where provided at the end of the command. */
int tempflag;
struct symtab_and_line sal;
char *addr_string = NULL;
- struct breakpoint_ops *ops = NULL;
+ const struct breakpoint_ops *ops = NULL;
tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
cmd_show_list (show_ada_list, from_tty, "");
}
+static void
+initialize_ada_catchpoint_ops (void)
+{
+ struct breakpoint_ops *ops;
+
+ initialize_breakpoint_ops ();
+
+ ops = &catch_exception_breakpoint_ops;
+ *ops = bkpt_breakpoint_ops;
+ ops->dtor = dtor_catch_exception;
+ ops->allocate_location = allocate_location_catch_exception;
+ ops->re_set = re_set_catch_exception;
+ ops->check_status = check_status_catch_exception;
+ ops->print_it = print_it_catch_exception;
+ ops->print_one = print_one_catch_exception;
+ ops->print_mention = print_mention_catch_exception;
+ ops->print_recreate = print_recreate_catch_exception;
+
+ ops = &catch_exception_unhandled_breakpoint_ops;
+ *ops = bkpt_breakpoint_ops;
+ ops->dtor = dtor_catch_exception_unhandled;
+ ops->allocate_location = allocate_location_catch_exception_unhandled;
+ ops->re_set = re_set_catch_exception_unhandled;
+ ops->check_status = check_status_catch_exception_unhandled;
+ ops->print_it = print_it_catch_exception_unhandled;
+ ops->print_one = print_one_catch_exception_unhandled;
+ ops->print_mention = print_mention_catch_exception_unhandled;
+ ops->print_recreate = print_recreate_catch_exception_unhandled;
+
+ ops = &catch_assert_breakpoint_ops;
+ *ops = bkpt_breakpoint_ops;
+ ops->dtor = dtor_catch_assert;
+ ops->allocate_location = allocate_location_catch_assert;
+ ops->re_set = re_set_catch_assert;
+ ops->check_status = check_status_catch_assert;
+ ops->print_it = print_it_catch_assert;
+ ops->print_one = print_one_catch_assert;
+ ops->print_mention = print_mention_catch_assert;
+ ops->print_recreate = print_recreate_catch_assert;
+}
+
void
_initialize_ada_language (void)
{
add_language (&ada_language_defn);
+ initialize_ada_catchpoint_ops ();
+
add_prefix_cmd ("ada", no_class, set_ada_command,
_("Prefix command for changing Ada-specfic settings"),
&set_ada_list, "set ada ", 0, &setlist);