-/* Ada language support routines for GDB, the GNU debugger. Copyright (C)
+/* Ada language support routines for GDB, the GNU debugger.
- 1992, 1993, 1994, 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008,
- 2009 Free Software Foundation, Inc.
+ Copyright (C) 1992-1994, 1997-2000, 2003-2005, 2007-2012 Free
+ Software Foundation, Inc.
This file is part of GDB.
#include "observer.h"
#include "vec.h"
#include "stack.h"
+#include "gdb_vecs.h"
#include "psymtab.h"
#include "value.h"
#include "mi/mi-common.h"
#include "arch-utils.h"
#include "exceptions.h"
+#include "cli/cli-utils.h"
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C).
static struct value *ada_value_primitive_field (struct value *, int, int,
struct type *);
-static int find_struct_field (char *, struct type *, int,
+static int find_struct_field (const char *, struct type *, int,
struct type **, int *, int *, int *, int *);
static struct value *ada_to_fixed_value_create (struct type *, CORE_ADDR,
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;
+
+ /* 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;
};
/* Our key to this module's inferior data. */
non-range scalar type. */
static struct type *
-base_type (struct type *type)
+get_base_type (struct type *type)
{
while (type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE)
{
/* 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);
+ const char *name = TYPE_FIELD_NAME (index_desc_type, i);
struct type *raw_type = ada_check_typedef (ada_find_any_type (name));
if (raw_type)
static long
decode_packed_array_bitsize (struct type *type)
{
- char *raw_name;
- char *tail;
+ const char *raw_name;
+ const char *tail;
long bits;
/* Access to arrays implemented as fat pointers are encoded as a typedef
static struct type *
decode_constrained_packed_array_type (struct type *type)
{
- char *raw_name = ada_type_name (ada_check_typedef (type));
+ const char *raw_name = ada_type_name (ada_check_typedef (type));
char *name;
- char *tail;
+ const char *tail;
struct type *shadow_type;
long bits;
ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
(exp->elts[pc + 2].symbol),
exp->elts[pc + 1].block, VAR_DOMAIN,
- &candidates);
+ &candidates, 1);
if (n_candidates > 1)
{
ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
(exp->elts[pc + 5].symbol),
exp->elts[pc + 4].block, VAR_DOMAIN,
- &candidates);
+ &candidates, 1);
if (n_candidates == 1)
i = 0;
else
n_candidates =
ada_lookup_symbol_list (ada_encode (ada_decoded_op_name (op)),
(struct block *) NULL, VAR_DOMAIN,
- &candidates);
+ &candidates, 1);
i = ada_resolve_function (candidates, n_candidates, argvec, nargs,
ada_decoded_op_name (op), NULL);
if (i < 0)
return 1;
if (TYPE_CODE (func_type) == TYPE_CODE_FUNC)
- return_type = base_type (TYPE_TARGET_TYPE (func_type));
+ return_type = get_base_type (TYPE_TARGET_TYPE (func_type));
else
- return_type = base_type (func_type);
+ return_type = get_base_type (func_type);
if (return_type == NULL)
return 1;
- context_type = base_type (context_type);
+ context_type = get_base_type (context_type);
if (TYPE_CODE (return_type) == TYPE_CODE_ENUM)
return context_type == NULL || return_type == context_type;
such symbols by their trailing number (__N or $N). */
static int
-encoded_ordered_before (char *N0, char *N1)
+encoded_ordered_before (const char *N0, const char *N1)
{
if (N1 == NULL)
return 0;
char *args2;
int choice, j;
- while (isspace (*args))
- args += 1;
+ args = skip_spaces (args);
if (*args == '\0' && n_chosen == 0)
error_no_arg (_("one or more choice numbers"));
else if (*args == '\0')
\f
/* Symbol Lookup */
+/* Return nonzero if wild matching should be used when searching for
+ all symbols matching LOOKUP_NAME.
+
+ LOOKUP_NAME is expected to be a symbol name after transformation
+ for Ada lookups (see ada_name_for_lookup). */
+
+static int
+should_use_wild_match (const char *lookup_name)
+{
+ return (strstr (lookup_name, "__") == NULL);
+}
+
/* Return the result of a standard (literal, C-like) lookup of NAME in
given DOMAIN, visible from lexical block BLOCK. */
{
struct type *type0 = SYMBOL_TYPE (sym0);
struct type *type1 = SYMBOL_TYPE (sym1);
- char *name0 = SYMBOL_LINKAGE_NAME (sym0);
- char *name1 = SYMBOL_LINKAGE_NAME (sym1);
+ const char *name0 = SYMBOL_LINKAGE_NAME (sym0);
+ const char *name1 = SYMBOL_LINKAGE_NAME (sym1);
int len0 = strlen (name0);
return
{
struct objfile *objfile;
struct minimal_symbol *msymbol;
- int wild_match;
+ const int wild_match = should_use_wild_match (name);
+ /* Special case: If the user specifies a symbol name inside package
+ Standard, do a non-wild matching of the symbol name without
+ the "standard__" prefix. This was primarily introduced in order
+ to allow the user to specifically access the standard exceptions
+ using, for instance, Standard.Constraint_Error when Constraint_Error
+ is ambiguous (due to the user defining its own Constraint_Error
+ entity inside its program). */
if (strncmp (name, "standard__", sizeof ("standard__") - 1) == 0)
- {
- name += sizeof ("standard__") - 1;
- wild_match = 0;
- }
- else
- wild_match = (strstr (name, "__") == NULL);
+ name += sizeof ("standard__") - 1;
ALL_MSYMBOLS (objfile, msymbol)
{
static int
is_nondebugging_type (struct type *type)
{
- char *name = ada_type_name (type);
+ const char *name = ada_type_name (type);
return (name != NULL && strcmp (name, "<variable, no debug info>") == 0);
}
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);
+ const char *name_1 = TYPE_FIELD_NAME (type1, i);
+ const char *name_2 = TYPE_FIELD_NAME (type2, i);
int len_1 = strlen (name_1);
int len_2 = strlen (name_2);
i = 0;
while (i < nsyms)
{
- int remove = 0;
+ int remove_p = 0;
/* If two symbols have the same name and one of them is a stub type,
the get rid of the stub. */
&& SYMBOL_LINKAGE_NAME (syms[j].sym) != NULL
&& strcmp (SYMBOL_LINKAGE_NAME (syms[i].sym),
SYMBOL_LINKAGE_NAME (syms[j].sym)) == 0)
- remove = 1;
+ remove_p = 1;
}
}
&& SYMBOL_CLASS (syms[i].sym) == SYMBOL_CLASS (syms[j].sym)
&& SYMBOL_VALUE_ADDRESS (syms[i].sym)
== SYMBOL_VALUE_ADDRESS (syms[j].sym))
- remove = 1;
+ remove_p = 1;
}
}
- if (remove)
+ if (remove_p)
{
for (j = i + 1; j < nsyms; j += 1)
syms[j - 1] = syms[j];
not visible from FUNCTION_NAME. */
static int
-old_renaming_is_invisible (const struct symbol *sym, char *function_name)
+old_renaming_is_invisible (const struct symbol *sym, const char *function_name)
{
char *scope;
int nsyms, const struct block *current_block)
{
struct symbol *current_function;
- char *current_function_name;
+ const char *current_function_name;
int i;
int is_new_style_renaming;
if (is_name_suffix (string1))
return 0;
else
- return -1;
+ return 1;
}
/* FALLTHROUGH */
default:
struct objfile *objfile;
struct match_data data;
+ memset (&data, 0, sizeof data);
data.obstackp = obstackp;
- data.arg_sym = NULL;
ALL_OBJFILES (objfile)
{
the next call of ada_lookup_symbol_list. Any non-function/non-enumeral
symbol match within the nest of blocks whose innermost member is BLOCK0,
is the one match returned (no other matches in that or
- enclosing blocks is returned). If there are any matches in or
- surrounding BLOCK0, then these alone are returned. Otherwise, the
- search extends to global and file-scope (static) symbol tables.
+ enclosing blocks is returned). If there are any matches in or
+ surrounding BLOCK0, then these alone are returned. Otherwise, if
+ FULL_SEARCH is non-zero, then the search extends to global and
+ file-scope (static) symbol tables.
Names prefixed with "standard__" are handled specially: "standard__"
is first stripped off, and only static and global symbols are searched. */
int
ada_lookup_symbol_list (const char *name0, const struct block *block0,
- domain_enum namespace,
- struct ada_symbol_info **results)
+ domain_enum namespace,
+ struct ada_symbol_info **results,
+ int full_search)
{
struct symbol *sym;
struct block *block;
const char *name;
- int wild_match;
+ const int wild_match = should_use_wild_match (name0);
int cacheIfUnique;
int ndefns;
/* Search specified block and its superiors. */
- wild_match = (strstr (name0, "__") == NULL);
name = name0;
block = (struct block *) block0; /* FIXME: No cast ought to be
needed, but adding const will
entity inside its program). */
if (strncmp (name0, "standard__", sizeof ("standard__") - 1) == 0)
{
- wild_match = 0;
block = NULL;
name = name0 + sizeof ("standard__") - 1;
}
ada_add_local_symbols (&symbol_list_obstack, name, block, namespace,
wild_match);
- if (num_defns_collected (&symbol_list_obstack) > 0)
+ if (num_defns_collected (&symbol_list_obstack) > 0 || !full_search)
goto done;
/* No non-global symbols found. Check our cache to see if we have
return ndefns;
}
+/* If NAME is the name of an entity, return a string that should
+ be used to look that entity up in Ada units. This string should
+ be deallocated after use using xfree.
+
+ NAME can have any form that the "break" or "print" commands might
+ recognize. In other words, it does not have to be the "natural"
+ name, or the "encoded" name. */
+
+char *
+ada_name_for_lookup (const char *name)
+{
+ char *canon;
+ int nlen = strlen (name);
+
+ if (name[0] == '<' && name[nlen - 1] == '>')
+ {
+ canon = xmalloc (nlen - 1);
+ memcpy (canon, name + 1, nlen - 2);
+ canon[nlen - 2] = '\0';
+ }
+ else
+ canon = xstrdup (ada_encode (ada_fold_name (name)));
+ return canon;
+}
+
+/* Implementation of the la_iterate_over_symbols method. */
+
+static void
+ada_iterate_over_symbols (const struct block *block,
+ const char *name, domain_enum domain,
+ symbol_found_callback_ftype *callback,
+ void *data)
+{
+ int ndefs, i;
+ struct ada_symbol_info *results;
+
+ ndefs = ada_lookup_symbol_list (name, block, domain, &results, 0);
+ for (i = 0; i < ndefs; ++i)
+ {
+ if (! (*callback) (results[i].sym, data))
+ break;
+ }
+}
+
struct symbol *
ada_lookup_encoded_symbol (const char *name, const struct block *block0,
domain_enum namespace, struct block **block_found)
struct ada_symbol_info *candidates;
int n_candidates;
- n_candidates = ada_lookup_symbol_list (name, block0, namespace, &candidates);
+ n_candidates = ada_lookup_symbol_list (name, block0, namespace, &candidates,
+ 1);
if (n_candidates == 0)
return NULL;
[.$][0-9]+ [nested subprogram suffix, on platforms such as GNU/Linux]
___[0-9]+ [nested subprogram suffix, on platforms such as HP/UX]
+ TKB [subprogram suffix for task bodies]
_E[0-9]+[bs]$ [protected object entry suffixes]
(X[nb]*)?((\$|__)[0-9](_?[0-9]+)|___(JM|LJM|X([FDBUP].*|R[^T]?)))?$
return 1;
}
+ /* "TKB" suffixes are used for subprograms implementing task bodies. */
+
+ if (strcmp (str, "TKB") == 0)
+ return 1;
+
#if 0
/* FIXME: brobecker/2005-09-23: Protected Object subprograms end
with a N at the end. Unfortunately, the compiler uses the same
return sym_name;
}
-DEF_VEC_P (char_ptr);
-
/* A companion function to ada_make_symbol_completion_list().
Check if SYM_NAME represents a symbol which name would be suitable
to complete TEXT (TEXT_LEN is the length of TEXT), in which case
static int
ada_is_dispatch_table_ptr_type (struct type *type)
{
- char *name;
+ const char *name;
if (TYPE_CODE (type) != TYPE_CODE_PTR)
return 0;
Returns 1 if found, 0 otherwise. */
static int
-find_struct_field (char *name, struct type *type, int offset,
+find_struct_field (const char *name, struct type *type, int offset,
struct type **field_type_p,
int *byte_offset_p, int *bit_offset_p, int *bit_size_p,
int *index_p)
{
int bit_pos = TYPE_FIELD_BITPOS (type, i);
int fld_offset = offset + bit_pos / 8;
- char *t_field_name = TYPE_FIELD_NAME (type, i);
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name == NULL)
continue;
type = ada_check_typedef (type);
for (i = 0; i < TYPE_NFIELDS (type); i += 1)
{
- char *t_field_name = TYPE_FIELD_NAME (type, i);
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name == NULL)
continue;
for (i = 0; i < TYPE_NFIELDS (type); i += 1)
{
- char *t_field_name = TYPE_FIELD_NAME (type, i);
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
struct type *t;
int disp;
NOT wrapped in a struct, since the compiler sometimes
generates these for unchecked variant types. Revisit
if the compiler changes this practice. */
- char *v_field_name = TYPE_FIELD_NAME (field_type, j);
+ const char *v_field_name = TYPE_FIELD_NAME (field_type, j);
disp = 0;
if (v_field_name != NULL
&& field_name_match (v_field_name, name))
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. */
- char *function_name = SYMBOL_LINKAGE_NAME (function_sym);
+ 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
/* The name of TYPE, which is either its TYPE_NAME, or, if that is
null, its TYPE_TAG_NAME. Null if TYPE is null. */
-char *
+const char *
ada_type_name (struct type *type)
{
if (type == NULL)
result = TYPE_DESCRIPTIVE_TYPE (type);
while (result != NULL)
{
- char *result_name = ada_type_name (result);
+ const char *result_name = ada_type_name (result);
if (result_name == NULL)
{
struct type *
ada_find_parallel_type (struct type *type, const char *suffix)
{
- char *name, *typename = ada_type_name (type);
+ char *name;
+ const char *typename = ada_type_name (type);
int len;
if (typename == NULL)
If there is, then it provides the actual size of our type. */
else if (ada_type_name (fixed_record_type) != NULL)
{
- char *name = ada_type_name (fixed_record_type);
+ const char *name = ada_type_name (fixed_record_type);
char *xvz_name = alloca (strlen (name) + 7 /* "___XVZ\0" */);
int xvz_found = 0;
LONGEST size;
return type;
else
{
- char *name = TYPE_TAG_NAME (type);
+ const char *name = TYPE_TAG_NAME (type);
struct type *type1 = ada_find_any_type (name);
if (type1 == NULL)
arg1 = coerce_ref (arg1);
arg2 = coerce_ref (arg2);
- type1 = base_type (ada_check_typedef (value_type (arg1)));
- type2 = base_type (ada_check_typedef (value_type (arg2)));
+ type1 = get_base_type (ada_check_typedef (value_type (arg1)));
+ type2 = get_base_type (ada_check_typedef (value_type (arg2)));
if (TYPE_CODE (type1) != TYPE_CODE_INT
|| TYPE_CODE (type2) != TYPE_CODE_INT)
*pos += 3;
if (noside != EVAL_NORMAL)
{
- int i;
-
for (i = 0; i < n; i += 1)
ada_evaluate_subexp (NULL, exp, pos, noside);
return container;
{
switch (exp->elts[*pos].opcode)
{
- case OP_CHOICES:
- aggregate_assign_from_choices (container, lhs, exp, pos, indices,
+ case OP_CHOICES:
+ aggregate_assign_from_choices (container, lhs, exp, pos, indices,
+ &num_indices, max_indices,
+ low_index, high_index);
+ break;
+ case OP_POSITIONAL:
+ aggregate_assign_positional (container, lhs, exp, pos, indices,
&num_indices, max_indices,
low_index, high_index);
- break;
- case OP_POSITIONAL:
- aggregate_assign_positional (container, lhs, exp, pos, indices,
- &num_indices, max_indices,
- low_index, high_index);
- break;
- case OP_OTHERS:
- if (i != n-1)
- error (_("Misplaced 'others' clause"));
- aggregate_assign_others (container, lhs, exp, pos, indices,
- num_indices, low_index, high_index);
- break;
- default:
- error (_("Internal error: bad aggregate clause"));
+ break;
+ case OP_OTHERS:
+ if (i != n-1)
+ error (_("Misplaced 'others' clause"));
+ aggregate_assign_others (container, lhs, exp, pos, indices,
+ num_indices, low_index, high_index);
+ break;
+ default:
+ error (_("Internal error: bad aggregate clause"));
}
}
else
{
int ind;
- char *name;
+ const char *name;
switch (op)
{
else if (discrete_type_p (type_arg))
{
struct type *range_type;
- char *name = ada_type_name (type_arg);
+ const char *name = ada_type_name (type_arg);
range_type = NULL;
if (name != NULL && TYPE_CODE (type_arg) != TYPE_CODE_ENUM)
int nsyms;
nsyms = ada_lookup_symbol_list (name, get_selected_block (0), VAR_DOMAIN,
- &syms);
+ &syms, 1);
if (nsyms != 1)
{
static struct type *
to_fixed_range_type (struct type *raw_type, struct value *dval)
{
- char *name;
+ const char *name;
struct type *base_type;
char *subtype_info;
int
ada_is_modular_type (struct type *type)
{
- struct type *subranged_type = base_type (type);
+ struct type *subranged_type = get_base_type (type);
return (subranged_type != NULL && TYPE_CODE (type) == TYPE_CODE_RANGE
&& TYPE_CODE (subranged_type) == TYPE_CODE_INT
int
ada_modulus_from_name (struct type *type, ULONGEST *modulus)
{
- char *name = ada_type_name (type);
- char *suffix;
+ const char *name = ada_type_name (type);
+ const char *suffix;
int k;
LONGEST U;
ada_unhandled_exception_name_addr_from_raise
};
-/* For each executable, we sniff which exception info structure to use
- and cache it in the following global variable. */
+/* Return nonzero if we can detect the exception support routines
+ described in EINFO.
-static const struct exception_support_info *exception_info = NULL;
+ This function errors out if an abnormal situation is detected
+ (for instance, if we find the exception support routines, but
+ that support is found to be incomplete). */
+
+static int
+ada_has_this_exception_support (const struct exception_support_info *einfo)
+{
+ struct symbol *sym;
+
+ /* The symbol we're looking up is provided by a unit in the GNAT runtime
+ that should be compiled with debugging information. As a result, we
+ expect to find that symbol in the symtabs. */
+
+ sym = standard_lookup (einfo->catch_exception_sym, NULL, VAR_DOMAIN);
+ if (sym == NULL)
+ {
+ /* Perhaps we did not find our symbol because the Ada runtime was
+ compiled without debugging info, or simply stripped of it.
+ It happens on some GNU/Linux distributions for instance, where
+ users have to install a separate debug package in order to get
+ the runtime's debugging info. In that situation, let the user
+ know why we cannot insert an Ada exception catchpoint.
+
+ Note: Just for the purpose of inserting our Ada exception
+ catchpoint, we could rely purely on the associated minimal symbol.
+ But we would be operating in degraded mode anyway, since we are
+ still lacking the debugging info needed later on to extract
+ the name of the exception being raised (this name is printed in
+ the catchpoint message, and is also used when trying to catch
+ a specific exception). We do not handle this case for now. */
+ if (lookup_minimal_symbol (einfo->catch_exception_sym, NULL, NULL))
+ error (_("Your Ada runtime appears to be missing some debugging "
+ "information.\nCannot insert Ada exception catchpoint "
+ "in this configuration."));
+
+ return 0;
+ }
+
+ /* Make sure that the symbol we found corresponds to a function. */
+
+ if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+ error (_("Symbol \"%s\" is not a function (class = %d)"),
+ SYMBOL_LINKAGE_NAME (sym), SYMBOL_CLASS (sym));
+
+ return 1;
+}
/* Inspect the Ada runtime and determine which exception info structure
should be used to provide support for exception catchpoints.
- This function will always set exception_info, or raise an error. */
+ This function will always set the per-inferior exception_info,
+ or raise an error. */
static void
ada_exception_support_info_sniffer (void)
{
+ struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
struct symbol *sym;
/* If the exception info is already known, then no need to recompute it. */
- if (exception_info != NULL)
+ if (data->exception_info != NULL)
return;
/* Check the latest (default) exception support info. */
- sym = standard_lookup (default_exception_support_info.catch_exception_sym,
- NULL, VAR_DOMAIN);
- if (sym != NULL)
+ if (ada_has_this_exception_support (&default_exception_support_info))
{
- exception_info = &default_exception_support_info;
+ data->exception_info = &default_exception_support_info;
return;
}
/* Try our fallback exception suport info. */
- sym = standard_lookup (exception_support_info_fallback.catch_exception_sym,
- NULL, VAR_DOMAIN);
- if (sym != NULL)
+ if (ada_has_this_exception_support (&exception_support_info_fallback))
{
- exception_info = &exception_support_info_fallback;
+ data->exception_info = &exception_support_info_fallback;
return;
}
out by the linker... In any case, at this point it is not worth
supporting this feature. */
- error (_("Cannot insert catchpoints in this configuration."));
-}
-
-/* An observer of "executable_changed" events.
- Its role is to clear certain cached values that need to be recomputed
- each time a new executable is loaded by GDB. */
-
-static void
-ada_executable_changed_observer (void)
-{
- /* If the executable changed, then it is possible that the Ada runtime
- is different. So we need to invalidate the exception support info
- cache. */
- exception_info = NULL;
+ error (_("Cannot insert Ada exception catchpoints in this configuration."));
}
/* True iff FRAME is very likely to be that of a function that is
is_known_support_routine (struct frame_info *frame)
{
struct symtab_and_line sal;
- char *func_name;
+ const char *func_name;
enum language func_lang;
int i;
{
int frame_level;
struct frame_info *fi;
+ struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
/* To determine the name of this exception, we need to select
the frame corresponding to RAISE_SYM_NAME. This frame is
while (fi != NULL)
{
- char *func_name;
+ const char *func_name;
enum language func_lang;
find_frame_funname (fi, &func_name, &func_lang, NULL);
if (func_name != NULL
- && strcmp (func_name, exception_info->catch_exception_sym) == 0)
+ && strcmp (func_name, data->exception_info->catch_exception_sym) == 0)
break; /* We found the frame we were looking for... */
fi = get_prev_frame (fi);
}
ada_exception_name_addr_1 (enum exception_catchpoint_kind ex,
struct breakpoint *b)
{
+ struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
+
switch (ex)
{
case ex_catch_exception:
break;
case ex_catch_exception_unhandled:
- return exception_info->unhandled_exception_name_addr ();
+ return data->exception_info->unhandled_exception_name_addr ();
break;
case ex_catch_assert:
ada_exception_name_addr (enum exception_catchpoint_kind ex,
struct breakpoint *b)
{
- struct gdb_exception e;
+ volatile struct gdb_exception e;
CORE_ADDR result = 0;
TRY_CATCH (e, RETURN_MASK_ERROR)
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.
static enum print_stop_action
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);
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 "));
default:
internal_error (__FILE__, __LINE__, _("unexpected catchpoint type"));
}
+ print_recreate_thread (b, fp);
}
/* Virtual table for "catch exception" breakpoints. */
char *end;
char *result;
- /* Skip any leading white space. */
-
- while (isspace (*args))
- args++;
-
+ args = skip_spaces (args);
if (args[0] == '\0')
return NULL; /* No more arguments. */
/* Find the end of the current argument. */
- end = args;
- while (*end != '\0' && !isspace (*end))
- end++;
+ end = skip_to_space (args);
/* Adjust ARGSP to point to the start of the next argument. */
/* Check that we do not have any more arguments. Anything else
is unexpected. */
- while (isspace (*args))
- args++;
+ args = skip_spaces (args);
if (args[0] != '\0')
error (_("Junk at end of expression"));
static const char *
ada_exception_sym_name (enum exception_catchpoint_kind ex)
{
- gdb_assert (exception_info != NULL);
+ struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
+
+ gdb_assert (data->exception_info != NULL);
switch (ex)
{
case ex_catch_exception:
- return (exception_info->catch_exception_sym);
+ return (data->exception_info->catch_exception_sym);
break;
case ex_catch_exception_unhandled:
- return (exception_info->catch_exception_unhandled_sym);
+ return (data->exception_info->catch_exception_unhandled_sym);
break;
case ex_catch_assert:
- return (exception_info->catch_assert_sym);
+ return (data->exception_info->catch_assert_sym);
break;
default:
internal_error (__FILE__, __LINE__,
/* 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;
- struct symtab_and_line sal;
/* First, find out which exception support info to use. */
ada_exception_support_info_sniffer ();
/* Then lookup the function on which we will break in order to catch
the Ada exceptions requested by the user. */
-
sym_name = ada_exception_sym_name (ex);
sym = standard_lookup (sym_name, NULL, VAR_DOMAIN);
- /* The symbol we're looking up is provided by a unit in the GNAT runtime
- that should be compiled with debugging information. As a result, we
- expect to find that symbol in the symtabs. If we don't find it, then
- the target most likely does not support Ada exceptions, or we cannot
- insert exception breakpoints yet, because the GNAT runtime hasn't been
- loaded yet. */
-
- /* brobecker/2006-12-26: It is conceivable that the runtime was compiled
- in such a way that no debugging information is produced for the symbol
- we are looking for. In this case, we could search the minimal symbols
- as a fall-back mechanism. This would still be operating in degraded
- mode, however, as we would still be missing the debugging information
- that is needed in order to extract the name of the exception being
- raised (this name is printed in the catchpoint message, and is also
- used when trying to catch a specific exception). We do not handle
- this case for now. */
-
- if (sym == NULL)
- error (_("Unable to break on '%s' in this configuration."), sym_name);
-
- /* Make sure that the symbol we found corresponds to a function. */
- if (SYMBOL_CLASS (sym) != LOC_BLOCK)
- error (_("Symbol \"%s\" is not a function (class = %d)"),
- sym_name, SYMBOL_CLASS (sym));
+ /* We can assume that SYM is not NULL at this stage. If the symbol
+ did not exist, ada_exception_support_info_sniffer would have
+ raised an exception.
- sal = find_function_start_sal (sym, 1);
+ Also, ada_exception_support_info_sniffer should have already
+ verified that SYM is a function symbol. */
+ gdb_assert (sym != NULL);
+ gdb_assert (SYMBOL_CLASS (sym) == LOC_BLOCK);
/* Set ADDR_STRING. */
-
*addr_string = xstrdup (sym_name);
/* Set OPS. */
*ops = ada_exception_breakpoint_ops (ex);
- return sal;
+ return find_function_start_sal (sym, 1);
}
/* Parse the arguments (ARGS) of the "catch exception" command.
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 (0, &c->base);
+ install_breakpoint (0, &c->base, 1);
}
/* 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. */
if (args != NULL)
{
- while (isspace (*args))
- args++;
+ args = skip_spaces (args);
if (*args != '\0')
error (_("Junk at end of arguments."));
}
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;
ada_evaluate_subexp
};
+/* Implement the "la_get_symbol_name_match_p" language_defn method
+ for Ada. */
+
+static symbol_name_match_p_ftype
+ada_get_symbol_name_match_p (const char *lookup_name)
+{
+ if (should_use_wild_match (lookup_name))
+ return wild_match;
+ else
+ return compare_names;
+}
+
const struct language_defn ada_language_defn = {
"ada", /* Language name */
language_ada,
ada_print_array_index,
default_pass_by_reference,
c_get_string,
+ ada_get_symbol_name_match_p, /* la_get_symbol_name_match_p */
+ ada_iterate_over_symbols,
LANG_MAGIC
};
(256, htab_hash_string, (int (*)(const void *, const void *)) streq,
NULL, xcalloc, xfree);
- observer_attach_executable_changed (ada_executable_changed_observer);
-
/* Setup per-inferior data. */
observer_attach_inferior_exit (ada_inferior_exit);
ada_inferior_data