#include "valprint.h"
#include "source.h"
#include "observable.h"
-#include "vec.h"
+#include "common/vec.h"
#include "stack.h"
-#include "gdb_vecs.h"
+#include "common/gdb_vecs.h"
#include "typeprint.h"
#include "namespace.h"
#include "common/function-view.h"
#include "common/byte-vector.h"
#include <algorithm>
+#include <map>
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C).
static struct block_symbol *defns_collected (struct obstack *, int);
static struct value *resolve_subexp (expression_up *, int *, int,
- struct type *);
+ struct type *, int,
+ innermost_block_tracker *);
static void replace_operator_with_call (expression_up *, int, int, int,
struct symbol *, const struct block *);
static int ada_resolve_function (struct block_symbol *, int,
struct value **, int, const char *,
- struct type *);
+ struct type *, int);
static int ada_is_direct_array_type (struct type *);
from_size = value_bitsize (fromval);
if (from_size == 0)
from_size = TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT;
- if (gdbarch_bits_big_endian (get_type_arch (type)))
- copy_bitwise (buffer, value_bitpos (toval),
- value_contents (fromval), from_size - bits, bits, 1);
- else
- copy_bitwise (buffer, value_bitpos (toval),
- value_contents (fromval), 0, bits, 0);
+
+ const int is_big_endian = gdbarch_bits_big_endian (get_type_arch (type));
+ ULONGEST from_offset = 0;
+ if (is_big_endian && is_scalar_type (value_type (fromval)))
+ from_offset = from_size - bits;
+ copy_bitwise (buffer, value_bitpos (toval),
+ value_contents (fromval), from_offset,
+ bits, is_big_endian);
write_memory_with_notification (to_addr, buffer, len);
val = value_copy (toval);
return high - low + 1;
}
-/* An empty array whose type is that of ARR_TYPE (an array type),
- with bounds LOW to LOW-1. */
+/* An array whose type is that of ARR_TYPE (an array type), with
+ bounds LOW to HIGH, but whose contents are unimportant. If HIGH is
+ less than LOW, then LOW-1 is used. */
static struct value *
-empty_array (struct type *arr_type, int low)
+empty_array (struct type *arr_type, int low, int high)
{
struct type *arr_type0 = ada_check_typedef (arr_type);
struct type *index_type
= create_static_range_type
- (NULL, TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (arr_type0)), low, low - 1);
+ (NULL, TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (arr_type0)), low,
+ high < low ? low - 1 : high);
struct type *elt_type = ada_array_element_type (arr_type0, 1);
return allocate_value (create_array_type (NULL, elt_type, index_type));
return type is preferred. May change (expand) *EXP. */
static void
-resolve (expression_up *expp, int void_context_p)
+resolve (expression_up *expp, int void_context_p, int parse_completion,
+ innermost_block_tracker *tracker)
{
struct type *context_type = NULL;
int pc = 0;
if (void_context_p)
context_type = builtin_type ((*expp)->gdbarch)->builtin_void;
- resolve_subexp (expp, &pc, 1, context_type);
+ resolve_subexp (expp, &pc, 1, context_type, parse_completion, tracker);
}
/* Resolve the operator of the subexpression beginning at
static struct value *
resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
- struct type *context_type)
+ struct type *context_type, int parse_completion,
+ innermost_block_tracker *tracker)
{
int pc = *pos;
int i;
else
{
*pos += 3;
- resolve_subexp (expp, pos, 0, NULL);
+ resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
}
nargs = longest_to_int (exp->elts[pc + 1].longconst);
break;
case UNOP_ADDR:
*pos += 1;
- resolve_subexp (expp, pos, 0, NULL);
+ resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
break;
case UNOP_QUAL:
*pos += 3;
- resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type));
+ resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type),
+ parse_completion, tracker);
break;
case OP_ATR_MODULUS:
struct value *arg1;
*pos += 1;
- arg1 = resolve_subexp (expp, pos, 0, NULL);
+ arg1 = resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
if (arg1 == NULL)
- resolve_subexp (expp, pos, 1, NULL);
+ resolve_subexp (expp, pos, 1, NULL, parse_completion, tracker);
else
- resolve_subexp (expp, pos, 1, value_type (arg1));
+ resolve_subexp (expp, pos, 1, value_type (arg1), parse_completion,
+ tracker);
break;
}
argvec = XALLOCAVEC (struct value *, nargs + 1);
for (i = 0; i < nargs; i += 1)
- argvec[i] = resolve_subexp (expp, pos, 1, NULL);
+ argvec[i] = resolve_subexp (expp, pos, 1, NULL, parse_completion,
+ tracker);
argvec[i] = NULL;
exp = expp->get ();
i = ada_resolve_function
(candidates.data (), n_candidates, NULL, 0,
SYMBOL_LINKAGE_NAME (exp->elts[pc + 2].symbol),
- context_type);
+ context_type, parse_completion);
if (i < 0)
error (_("Could not find a match for %s"),
SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
exp->elts[pc + 1].block = candidates[i].block;
exp->elts[pc + 2].symbol = candidates[i].symbol;
- innermost_block.update (candidates[i]);
+ tracker->update (candidates[i]);
}
if (deprocedure_p
(candidates.data (), n_candidates,
argvec, nargs,
SYMBOL_LINKAGE_NAME (exp->elts[pc + 5].symbol),
- context_type);
+ context_type, parse_completion);
if (i < 0)
error (_("Could not find a match for %s"),
SYMBOL_PRINT_NAME (exp->elts[pc + 5].symbol));
exp->elts[pc + 4].block = candidates[i].block;
exp->elts[pc + 5].symbol = candidates[i].symbol;
- innermost_block.update (candidates[i]);
+ tracker->update (candidates[i]);
}
}
break;
n_candidates =
ada_lookup_symbol_list (ada_decoded_op_name (op),
- (struct block *) NULL, VAR_DOMAIN,
+ NULL, VAR_DOMAIN,
&candidates);
i = ada_resolve_function (candidates.data (), n_candidates, argvec,
- nargs, ada_decoded_op_name (op), NULL);
+ nargs, ada_decoded_op_name (op), NULL,
+ parse_completion);
if (i < 0)
break;
static int
ada_resolve_function (struct block_symbol syms[],
int nsyms, struct value **args, int nargs,
- const char *name, struct type *context_type)
+ const char *name, struct type *context_type,
+ int parse_completion)
{
int fallback;
int k;
error (_("\
canceled because the command is ambiguous\n\
See set/show multiple-symbol."));
-
+
/* If select_mode is "all", then return all possible symbols.
Only do that if more than one symbol can be selected, of course.
Otherwise, display the menu as usual. */
if (select_mode == multiple_symbols_all && max_results > 1)
return nsyms;
- printf_unfiltered (_("[0] cancel\n"));
+ printf_filtered (_("[0] cancel\n"));
if (max_results > 1)
- printf_unfiltered (_("[1] all\n"));
+ printf_filtered (_("[1] all\n"));
sort_choices (syms, nsyms);
struct symtab_and_line sal =
find_function_start_sal (syms[i].symbol, 1);
- printf_unfiltered ("[%d] ", i + first_choice);
+ printf_filtered ("[%d] ", i + first_choice);
ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
&type_print_raw_options);
if (sal.symtab == NULL)
- printf_unfiltered (_(" at <no source file available>:%d\n"),
- sal.line);
+ printf_filtered (_(" at <no source file available>:%d\n"),
+ sal.line);
else
- printf_unfiltered (_(" at %s:%d\n"),
- symtab_to_filename_for_display (sal.symtab),
- sal.line);
+ printf_filtered (_(" at %s:%d\n"),
+ symtab_to_filename_for_display (sal.symtab),
+ sal.line);
continue;
}
else
if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL)
{
- printf_unfiltered ("[%d] ", i + first_choice);
+ printf_filtered ("[%d] ", i + first_choice);
ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
&type_print_raw_options);
- printf_unfiltered (_(" at %s:%d\n"),
- symtab_to_filename_for_display (symtab),
- SYMBOL_LINE (syms[i].symbol));
+ printf_filtered (_(" at %s:%d\n"),
+ symtab_to_filename_for_display (symtab),
+ SYMBOL_LINE (syms[i].symbol));
}
else if (is_enumeral
&& TYPE_NAME (SYMBOL_TYPE (syms[i].symbol)) != NULL)
{
- printf_unfiltered (("[%d] "), i + first_choice);
+ printf_filtered (("[%d] "), i + first_choice);
ada_print_type (SYMBOL_TYPE (syms[i].symbol), NULL,
gdb_stdout, -1, 0, &type_print_raw_options);
- printf_unfiltered (_("'(%s) (enumeral)\n"),
- SYMBOL_PRINT_NAME (syms[i].symbol));
+ printf_filtered (_("'(%s) (enumeral)\n"),
+ SYMBOL_PRINT_NAME (syms[i].symbol));
}
else
{
- printf_unfiltered ("[%d] ", i + first_choice);
+ printf_filtered ("[%d] ", i + first_choice);
ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
&type_print_raw_options);
if (symtab != NULL)
- printf_unfiltered (is_enumeral
- ? _(" in %s (enumeral)\n")
- : _(" at %s:?\n"),
- symtab_to_filename_for_display (symtab));
+ printf_filtered (is_enumeral
+ ? _(" in %s (enumeral)\n")
+ : _(" at %s:?\n"),
+ symtab_to_filename_for_display (symtab));
else
- printf_unfiltered (is_enumeral
- ? _(" (enumeral)\n")
- : _(" at ?\n"));
+ printf_filtered (is_enumeral
+ ? _(" (enumeral)\n")
+ : _(" at ?\n"));
}
}
}
domain_enum domain)
{
/* Initialize it just to avoid a GCC false warning. */
- struct block_symbol sym = {NULL, NULL};
+ struct block_symbol sym = {};
if (lookup_cached_symbol (name, domain, &sym.symbol, NULL))
return sym.symbol;
- sym = lookup_symbol_in_language (name, block, domain, language_c, 0);
+ ada_lookup_encoded_symbol (name, block, domain, &sym);
cache_symbol (name, domain, sym.symbol, sym.block);
return sym.symbol;
}
symbol_name_matcher_ftype *match_name
= ada_get_symbol_name_matcher (lookup_name);
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
if (match_name (MSYMBOL_LINKAGE_NAME (msymbol), lookup_name, NULL)
&& MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
return result;
}
+/* Return all the bound minimal symbols matching NAME according to Ada
+ decoding rules. Returns an empty vector if there is no such
+ minimal symbol. Names prefixed with "standard__" are handled
+ specially: "standard__" is first stripped off, and only static and
+ global symbols are searched. */
+
+static std::vector<struct bound_minimal_symbol>
+ada_lookup_simple_minsyms (const char *name)
+{
+ std::vector<struct bound_minimal_symbol> result;
+
+ symbol_name_match_type match_type = name_match_type_from_name (name);
+ lookup_name_info lookup_name (name, match_type);
+
+ symbol_name_matcher_ftype *match_name
+ = ada_get_symbol_name_matcher (lookup_name);
+
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ for (minimal_symbol *msymbol : objfile->msymbols ())
+ {
+ if (match_name (MSYMBOL_LINKAGE_NAME (msymbol), lookup_name, NULL)
+ && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
+ result.push_back ({msymbol, objfile});
+ }
+ }
+
+ return result;
+}
+
/* For all subprograms that statically enclose the subprogram of the
selected frame, add symbols matching identifier NAME in DOMAIN
and their blocks to the list of data in OBSTACKP, as for
other has been found. */
static int
-aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0)
+aux_add_nonlocal_symbols (const struct block *block, struct symbol *sym,
+ void *data0)
{
struct match_data *data = (struct match_data *) data0;
bool is_wild_match = lookup_name.ada ().wild_match_p ();
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
data.objfile = objfile;
symbol_name_match_type::FULL,
compare_names);
- for (compunit_symtab *cu : objfile_compunits (objfile))
+ for (compunit_symtab *cu : objfile->compunits ())
{
const struct block *global_block
= BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK);
const char *name = ada_lookup_name (lookup_name);
std::string name1 = std::string ("<_ada_") + name + '>';
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
data.objfile = objfile;
objfile->sf->qf->map_matching_symbols (objfile, name1.c_str (),
return sym;
}
- return (struct block_symbol) {NULL, NULL};
+ return {};
}
anything that isn't a text symbol (everything else will be
handled by the psymtab code above). */
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
- for (minimal_symbol *msymbol : objfile_msymbols (objfile))
+ for (minimal_symbol *msymbol : objfile->msymbols ())
{
QUIT;
/* Go through the symtabs and check the externs and statics for
symbols which match. */
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
- for (compunit_symtab *s : objfile_compunits (objfile))
+ for (compunit_symtab *s : objfile->compunits ())
{
QUIT;
b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), GLOBAL_BLOCK);
}
}
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
- for (compunit_symtab *s : objfile_compunits (objfile))
+ for (compunit_symtab *s : objfile->compunits ())
{
QUIT;
b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), STATIC_BLOCK);
see ada_tag_name for more details. We do not print the error
message for the same reason. */
- TRY
+ try
{
offset_to_top = value_as_long (value_ind (value_ptradd (val, -2)));
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
return obj;
}
- END_CATCH
/* If offset is null, nothing to do. */
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
+ try
{
struct value *tsd = ada_get_tsd_from_tag (tag);
if (tsd != NULL)
name = ada_tag_name_from_tsd (tsd);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
}
- END_CATCH
return name;
}
int
ada_is_variant_part (struct type *type, int field_num)
{
+ /* Only Ada types are eligible. */
+ if (!ADA_TYPE_P (type))
+ return 0;
+
struct type *field_type = TYPE_FIELD_TYPE (type, field_num);
return (TYPE_CODE (field_type) == TYPE_CODE_UNION
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);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_NFIELDS (type) = 0;
TYPE_FIELDS (type) = NULL;
- INIT_CPLUS_SPECIFIC (type);
+ INIT_NONE_SPECIFIC (type);
TYPE_NAME (type) = "<empty>";
TYPE_LENGTH (type) = 0;
return type;
rtype = alloc_type_copy (type);
TYPE_CODE (rtype) = TYPE_CODE_STRUCT;
- INIT_CPLUS_SPECIFIC (rtype);
+ INIT_NONE_SPECIFIC (rtype);
TYPE_NFIELDS (rtype) = nfields;
TYPE_FIELDS (rtype) = (struct field *)
TYPE_ALLOC (rtype, nfields * sizeof (struct field));
if (TYPE_LENGTH (type) <= 0)
{
if (TYPE_NAME (rtype))
- warning (_("Invalid type size for `%s' detected: %d."),
- TYPE_NAME (rtype), TYPE_LENGTH (type));
+ warning (_("Invalid type size for `%s' detected: %s."),
+ TYPE_NAME (rtype), pulongest (TYPE_LENGTH (type)));
else
- warning (_("Invalid type size for <unnamed> detected: %d."),
- TYPE_LENGTH (type));
+ warning (_("Invalid type size for <unnamed> detected: %s."),
+ pulongest (TYPE_LENGTH (type)));
}
else
{
{
TYPE_TARGET_TYPE (type0) = type = alloc_type_copy (type0);
TYPE_CODE (type) = TYPE_CODE (type0);
- INIT_CPLUS_SPECIFIC (type);
+ INIT_NONE_SPECIFIC (type);
TYPE_NFIELDS (type) = nfields;
TYPE_FIELDS (type) = (struct field *)
TYPE_ALLOC (type, nfields * sizeof (struct field));
rtype = alloc_type_copy (type);
TYPE_CODE (rtype) = TYPE_CODE_STRUCT;
- INIT_CPLUS_SPECIFIC (rtype);
+ INIT_NONE_SPECIFIC (rtype);
TYPE_NFIELDS (rtype) = nfields;
TYPE_FIELDS (rtype) =
(struct field *) TYPE_ALLOC (rtype, nfields * sizeof (struct field));
CORE_ADDR address, struct value *dval, int check_tag)
{
type = ada_check_typedef (type);
+
+ /* Only un-fixed types need to be handled here. */
+ if (!HAVE_GNAT_AUX_INFO (type))
+ return type;
+
switch (TYPE_CODE (type))
{
default:
LONGEST size;
xsnprintf (xvz_name, strlen (name) + 7, "%s___XVZ", name);
- TRY
+ try
{
xvz_found = get_int_var_value (xvz_name, size);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
/* We found the variable, but somehow failed to read
its value. Rethrow the same error, but with a little
optimized out). */
throw_error (except.error,
_("unable to read value of %s (%s)"),
- xvz_name, except.message);
+ xvz_name, except.what ());
}
- END_CATCH
if (xvz_found && TYPE_LENGTH (fixed_record_type) != size)
{
[At the moment, this is true only for Character and Wide_Character;
It is a heuristic test that could stand improvement]. */
-int
+bool
ada_is_character_type (struct type *type)
{
const char *name;
/* If the type code says it's a character, then assume it really is,
and don't check any further. */
if (TYPE_CODE (type) == TYPE_CODE_CHAR)
- return 1;
+ return true;
/* Otherwise, assume it's a character type iff it is a discrete type
with a known character type name. */
/* True if TYPE appears to be an Ada string type. */
-int
+bool
ada_is_string_type (struct type *type)
{
type = ada_check_typedef (type);
return ada_is_character_type (elttype);
}
else
- return 0;
+ return false;
}
/* The compiler sometimes provides a parallel XVS type for a given
if (noside == EVAL_AVOID_SIDE_EFFECTS
&& ada_is_array_descriptor_type (ada_check_typedef
(value_type (array))))
- return empty_array (ada_type_of_array (array, 0), low_bound);
+ return empty_array (ada_type_of_array (array, 0), low_bound,
+ high_bound);
array = ada_coerce_to_simple_array_ptr (array);
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 (type0), low_bound);
+ return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound);
else
{
struct type *arr_type0 =
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
return array;
else if (high_bound < low_bound)
- return empty_array (value_type (array), low_bound);
+ return empty_array (value_type (array), low_bound, high_bound);
else
return ada_value_slice (array, longest_to_int (low_bound),
longest_to_int (high_bound));
{
gdb::unique_xmalloc_ptr<char> e_msg;
- TRY
+ try
{
e_msg = ada_exception_message_1 ();
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
e_msg.reset (nullptr);
}
- END_CATCH
return e_msg;
}
{
CORE_ADDR result = 0;
- TRY
+ try
{
result = ada_exception_name_addr_1 (ex, b);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
- warning (_("failed to get exception name: %s"), e.message);
+ warning (_("failed to get exception name: %s"), e.what ());
return 0;
}
- END_CATCH
return result;
}
class ada_catchpoint_location : public bp_location
{
public:
- ada_catchpoint_location (const bp_location_ops *ops, breakpoint *owner)
- : bp_location (ops, owner)
+ ada_catchpoint_location (breakpoint *owner)
+ : bp_location (owner)
{}
/* The condition that checks whether the exception that was raised
expression_up excep_cond_expr;
};
-/* Implement the DTOR method in the bp_location_ops structure for all
- Ada exception catchpoint kinds. */
-
-static void
-ada_catchpoint_location_dtor (struct bp_location *bl)
-{
- struct ada_catchpoint_location *al = (struct ada_catchpoint_location *) bl;
-
- al->excep_cond_expr.reset ();
-}
-
-/* The vtable to be used in Ada catchpoint locations. */
-
-static const struct bp_location_ops ada_catchpoint_location_ops =
-{
- ada_catchpoint_location_dtor
-};
-
/* An instance of this type is used to represent an Ada catchpoint. */
struct ada_catchpoint : public breakpoint
create_excep_cond_exprs (struct ada_catchpoint *c,
enum ada_exception_catchpoint_kind ex)
{
- struct bp_location *bl;
-
/* Nothing to do if there's no specific exception to catch. */
if (c->excep_string.empty ())
return;
if (c->loc == NULL)
return;
- /* Compute the condition expression in text form, from the specific
- expection we want to catch. */
- std::string cond_string
- = ada_exception_catchpoint_cond_string (c->excep_string.c_str (), ex);
+ /* We have to compute the expression once for each program space,
+ 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)
+ loc_map.emplace (bl->pspace, bl);
+
+ scoped_restore_current_program_space save_pspace;
- /* Iterate over all the catchpoint's locations, and parse an
- expression for each. */
- for (bl = c->loc; bl != NULL; bl = bl->next)
+ std::string cond_string;
+ program_space *last_ps = nullptr;
+ for (auto iter : loc_map)
{
struct ada_catchpoint_location *ada_loc
- = (struct ada_catchpoint_location *) bl;
+ = (struct ada_catchpoint_location *) iter.second;
+
+ if (ada_loc->pspace != last_ps)
+ {
+ last_ps = ada_loc->pspace;
+ set_current_program_space (last_ps);
+
+ /* Compute the condition expression in text form, from the
+ specific expection we want to catch. */
+ cond_string
+ = ada_exception_catchpoint_cond_string (c->excep_string.c_str (),
+ ex);
+ }
+
expression_up exp;
- if (!bl->shlib_disabled)
+ if (!ada_loc->shlib_disabled)
{
const char *s;
s = cond_string.c_str ();
- TRY
+ try
{
- exp = parse_exp_1 (&s, bl->address,
- block_for_pc (bl->address),
+ exp = parse_exp_1 (&s, ada_loc->address,
+ block_for_pc (ada_loc->address),
0);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
warning (_("failed to reevaluate internal exception condition "
"for catchpoint %d: %s"),
- c->number, e.message);
+ c->number, e.what ());
}
- END_CATCH
}
ada_loc->excep_cond_expr = std::move (exp);
allocate_location_exception (enum ada_exception_catchpoint_kind ex,
struct breakpoint *self)
{
- return new ada_catchpoint_location (&ada_catchpoint_location_ops, self);
+ return new ada_catchpoint_location (self);
}
/* Implement the RE_SET method in the breakpoint_ops structure for all
}
stop = 1;
- TRY
+ try
{
struct value *mark;
stop = value_true (evaluate_expression (ada_loc->excep_cond_expr.get ()));
value_free_to_mark (mark);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
_("Error in testing exception condition:\n"));
}
- END_CATCH
return stop;
}
enum ada_exception_catchpoint_kind ex)
{
int i;
- bool is_standard_exc = false;
std::string result;
+ const char *name;
if (ex == ada_catch_handlers)
{
/* For exception handlers catchpoints, the condition string does
not use the same parameter as for the other exceptions. */
- result = ("long_integer (GNAT_GCC_exception_Access"
- "(gcc_exception).all.occurrence.id)");
+ name = ("long_integer (GNAT_GCC_exception_Access"
+ "(gcc_exception).all.occurrence.id)");
}
else
- result = "long_integer (e)";
+ name = "long_integer (e)";
/* The standard exceptions are a special case. They are defined in
runtime units that have been compiled without debugging info; if
If an exception named contraint_error is defined in another package of
the inferior program, then the only way to specify this exception as a
breakpoint condition is to use its fully-qualified named:
- e.g. my_package.constraint_error. */
+ e.g. my_package.constraint_error.
+
+ Furthermore, in some situations a standard exception's symbol may
+ be present in more than one objfile, because the compiler may
+ choose to emit copy relocations for them. So, we have to compare
+ against all the possible addresses. */
+ /* Storage for a rewritten symbol name. */
+ std::string std_name;
for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
{
if (strcmp (standard_exc [i], excep_string) == 0)
{
- is_standard_exc = true;
+ std_name = std::string ("standard.") + excep_string;
+ excep_string = std_name.c_str ();
break;
}
}
- result += " = ";
-
- if (is_standard_exc)
- string_appendf (result, "long_integer (&standard.%s)", excep_string);
- else
- string_appendf (result, "long_integer (&%s)", excep_string);
+ 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)
+ {
+ if (!result.empty ())
+ result += " or ";
+ string_appendf (result, "%s = %s", name,
+ pulongest (BMSYMBOL_VALUE_ADDRESS (msym)));
+ }
return result;
}
static struct symtab_and_line
ada_exception_sal (enum ada_exception_catchpoint_kind ex,
- const char **addr_string, const struct breakpoint_ops **ops)
+ std::string *addr_string, const struct breakpoint_ops **ops)
{
const char *sym_name;
struct symbol *sym;
error (_("Unable to insert catchpoint. %s is not a function."), sym_name);
/* Set ADDR_STRING. */
- *addr_string = xstrdup (sym_name);
+ *addr_string = sym_name;
/* Set OPS. */
*ops = ada_exception_breakpoint_ops (ex);
int disabled,
int from_tty)
{
- const char *addr_string = NULL;
+ std::string addr_string;
const struct breakpoint_ops *ops = NULL;
struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string, &ops);
std::unique_ptr<ada_catchpoint> c (new ada_catchpoint ());
- init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string,
+ init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string.c_str (),
ops, tempflag, disabled, from_tty);
c->excep_string = excep_string;
create_excep_cond_exprs (c.get (), ex_kind);
NULL,
VARIABLES_DOMAIN);
- for (objfile *objfile : all_objfiles (current_program_space))
+ for (objfile *objfile : current_program_space->objfiles ())
{
- for (compunit_symtab *s : objfile_compunits (objfile))
+ for (compunit_symtab *s : objfile->compunits ())
{
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (s);
int i;
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
{
- struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+ const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
struct block_iterator iter;
struct symbol *sym;
return full_match (symbol_search_name, ada_lookup_name (lookup_name));
}
+/* symbol_name_matcher_ftype for exact (verbatim) matches. */
+
+static bool
+do_exact_match (const char *symbol_search_name,
+ const lookup_name_info &lookup_name,
+ completion_match_result *comp_match_res)
+{
+ return strcmp (symbol_search_name, ada_lookup_name (lookup_name)) == 0;
+}
+
/* Build the Ada lookup name for LOOKUP_NAME. */
ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
{
if (lookup_name.ada ().wild_match_p ())
return do_wild_match;
+ else if (lookup_name.ada ().verbatim_p ())
+ return do_exact_match;
else
return do_full_match;
}
&ada_varobj_ops,
NULL,
NULL,
- LANG_MAGIC
+ ada_is_string_type,
+ "(...)" /* la_struct_too_deep_ellipsis */
};
/* Command-list for the "set/show ada" prefix command. */
add_catch_command ("exception", _("\
Catch Ada exceptions, when raised.\n\
-With an argument, catch only exceptions with the given name."),
+Usage: catch exception [ ARG ]\n\
+\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."),
catch_ada_exception_command,
NULL,
CATCH_PERMANENT,