/* Ada language support routines for GDB, the GNU debugger.
- Copyright (C) 1992-2018 Free Software Foundation, Inc.
+ Copyright (C) 1992-2019 Free Software Foundation, Inc.
This file is part of GDB.
#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"
static struct value *value_subscript_packed (struct value *, int,
struct value **);
-static void move_bits (gdb_byte *, int, const gdb_byte *, int, int, int);
-
static struct value *coerce_unspec_val_to_type (struct value *,
struct type *);
return v;
}
-/* Move N bits from SOURCE, starting at bit offset SRC_OFFSET to
- TARGET, starting at bit offset TARG_OFFSET. SOURCE and TARGET must
- not overlap. */
-static void
-move_bits (gdb_byte *target, int targ_offset, const gdb_byte *source,
- int src_offset, int n, int bits_big_endian_p)
-{
- unsigned int accum, mask;
- int accum_bits, chunk_size;
-
- target += targ_offset / HOST_CHAR_BIT;
- targ_offset %= HOST_CHAR_BIT;
- source += src_offset / HOST_CHAR_BIT;
- src_offset %= HOST_CHAR_BIT;
- if (bits_big_endian_p)
- {
- accum = (unsigned char) *source;
- source += 1;
- accum_bits = HOST_CHAR_BIT - src_offset;
-
- while (n > 0)
- {
- int unused_right;
-
- accum = (accum << HOST_CHAR_BIT) + (unsigned char) *source;
- accum_bits += HOST_CHAR_BIT;
- source += 1;
- chunk_size = HOST_CHAR_BIT - targ_offset;
- if (chunk_size > n)
- chunk_size = n;
- unused_right = HOST_CHAR_BIT - (chunk_size + targ_offset);
- mask = ((1 << chunk_size) - 1) << unused_right;
- *target =
- (*target & ~mask)
- | ((accum >> (accum_bits - chunk_size - unused_right)) & mask);
- n -= chunk_size;
- accum_bits -= chunk_size;
- target += 1;
- targ_offset = 0;
- }
- }
- else
- {
- accum = (unsigned char) *source >> src_offset;
- source += 1;
- accum_bits = HOST_CHAR_BIT - src_offset;
-
- while (n > 0)
- {
- accum = accum + ((unsigned char) *source << accum_bits);
- accum_bits += HOST_CHAR_BIT;
- source += 1;
- chunk_size = HOST_CHAR_BIT - targ_offset;
- if (chunk_size > n)
- chunk_size = n;
- mask = ((1 << chunk_size) - 1) << targ_offset;
- *target = (*target & ~mask) | ((accum << targ_offset) & mask);
- n -= chunk_size;
- accum_bits -= chunk_size;
- accum >>= chunk_size;
- target += 1;
- targ_offset = 0;
- }
- }
-}
-
/* Store the contents of FROMVAL into the location of TOVAL.
Return a new value with the location of TOVAL and contents of
FROMVAL. Handles assignment into packed fields that have
if (from_size == 0)
from_size = TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT;
if (gdbarch_bits_big_endian (get_type_arch (type)))
- move_bits (buffer, value_bitpos (toval),
- value_contents (fromval), from_size - bits, bits, 1);
+ copy_bitwise (buffer, value_bitpos (toval),
+ value_contents (fromval), from_size - bits, bits, 1);
else
- move_bits (buffer, value_bitpos (toval),
- value_contents (fromval), 0, bits, 0);
+ copy_bitwise (buffer, value_bitpos (toval),
+ value_contents (fromval), 0, bits, 0);
write_memory_with_notification (to_addr, buffer, len);
val = value_copy (toval);
= TYPE_LENGTH (value_type (component)) * TARGET_CHAR_BIT - bits;
else
src_offset = 0;
- move_bits (value_contents_writeable (container) + offset_in_container,
- value_bitpos (container) + bit_offset_in_container,
- value_contents (val), src_offset, bits, 1);
+ copy_bitwise (value_contents_writeable (container) + offset_in_container,
+ value_bitpos (container) + bit_offset_in_container,
+ value_contents (val), src_offset, bits, 1);
}
else
- move_bits (value_contents_writeable (container) + offset_in_container,
- value_bitpos (container) + bit_offset_in_container,
- value_contents (val), 0, bits, 0);
+ copy_bitwise (value_contents_writeable (container) + offset_in_container,
+ value_bitpos (container) + bit_offset_in_container,
+ value_contents (val), 0, bits, 0);
}
/* Determine if TYPE is an access to an unconstrained array. */
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"));
}
}
}
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;
}
ada_lookup_simple_minsym (const char *name)
{
struct bound_minimal_symbol result;
- struct objfile *objfile;
- struct minimal_symbol *msymbol;
memset (&result, 0, sizeof (result));
symbol_name_matcher_ftype *match_name
= ada_get_symbol_name_matcher (lookup_name);
- ALL_MSYMBOLS (objfile, msymbol)
- {
- if (match_name (MSYMBOL_LINKAGE_NAME (msymbol), lookup_name, NULL)
- && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
- {
- result.minsym = msymbol;
- result.objfile = objfile;
- break;
- }
- }
+ 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.minsym = msymbol;
+ result.objfile = objfile;
+ break;
+ }
+ }
+ }
return result;
}
const lookup_name_info &lookup_name,
domain_enum domain, int global)
{
- struct objfile *objfile;
- struct compunit_symtab *cu;
struct match_data data;
memset (&data, 0, sizeof data);
bool is_wild_match = lookup_name.ada ().wild_match_p ();
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
data.objfile = objfile;
symbol_name_match_type::FULL,
compare_names);
- ALL_OBJFILE_COMPUNITS (objfile, cu)
+ 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 + '>';
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
data.objfile = objfile;
objfile->sf->qf->map_matching_symbols (objfile, name1.c_str (),
enum type_code code)
{
struct symbol *sym;
- struct compunit_symtab *s;
- struct minimal_symbol *msymbol;
- struct objfile *objfile;
const struct block *b, *surrounding_static_block = 0;
struct block_iterator iter;
anything that isn't a text symbol (everything else will be
handled by the psymtab code above). */
- ALL_MSYMBOLS (objfile, msymbol)
- {
- QUIT;
-
- if (completion_skip_symbol (mode, msymbol))
- continue;
-
- language symbol_language = MSYMBOL_LANGUAGE (msymbol);
-
- /* Ada minimal symbols won't have their language set to Ada. If
- we let completion_list_add_name compare using the
- default/C-like matcher, then when completing e.g., symbols in a
- package named "pck", we'd match internal Ada symbols like
- "pckS", which are invalid in an Ada expression, unless you wrap
- them in '<' '>' to request a verbatim match.
-
- Unfortunately, some Ada encoded names successfully demangle as
- C++ symbols (using an old mangling scheme), such as "name__2Xn"
- -> "Xn::name(void)" and thus some Ada minimal symbols end up
- with the wrong language set. Paper over that issue here. */
- if (symbol_language == language_auto
- || symbol_language == language_cplus)
- symbol_language = language_ada;
-
- completion_list_add_name (tracker,
- symbol_language,
- MSYMBOL_LINKAGE_NAME (msymbol),
- lookup_name, text, word);
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ for (minimal_symbol *msymbol : objfile->msymbols ())
+ {
+ QUIT;
+
+ if (completion_skip_symbol (mode, msymbol))
+ continue;
+
+ language symbol_language = MSYMBOL_LANGUAGE (msymbol);
+
+ /* Ada minimal symbols won't have their language set to Ada. If
+ we let completion_list_add_name compare using the
+ default/C-like matcher, then when completing e.g., symbols in a
+ package named "pck", we'd match internal Ada symbols like
+ "pckS", which are invalid in an Ada expression, unless you wrap
+ them in '<' '>' to request a verbatim match.
+
+ Unfortunately, some Ada encoded names successfully demangle as
+ C++ symbols (using an old mangling scheme), such as "name__2Xn"
+ -> "Xn::name(void)" and thus some Ada minimal symbols end up
+ with the wrong language set. Paper over that issue here. */
+ if (symbol_language == language_auto
+ || symbol_language == language_cplus)
+ symbol_language = language_ada;
+
+ completion_list_add_name (tracker,
+ symbol_language,
+ MSYMBOL_LINKAGE_NAME (msymbol),
+ lookup_name, text, word);
+ }
+ }
/* Search upwards from currently selected frame (so that we can
complete on local vars. */
/* Go through the symtabs and check the externs and statics for
symbols which match. */
- ALL_COMPUNITS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, iter, sym)
+ for (objfile *objfile : current_program_space->objfiles ())
{
- if (completion_skip_symbol (mode, sym))
- continue;
+ for (compunit_symtab *s : objfile->compunits ())
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ if (completion_skip_symbol (mode, sym))
+ continue;
- completion_list_add_name (tracker,
- SYMBOL_LANGUAGE (sym),
- SYMBOL_LINKAGE_NAME (sym),
- lookup_name, text, word);
+ completion_list_add_name (tracker,
+ SYMBOL_LANGUAGE (sym),
+ SYMBOL_LINKAGE_NAME (sym),
+ lookup_name, text, word);
+ }
+ }
}
- }
- ALL_COMPUNITS (objfile, s)
- {
- QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- if (completion_skip_symbol (mode, sym))
- continue;
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ for (compunit_symtab *s : objfile->compunits ())
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ if (completion_skip_symbol (mode, sym))
+ continue;
- completion_list_add_name (tracker,
- SYMBOL_LANGUAGE (sym),
- SYMBOL_LINKAGE_NAME (sym),
- lookup_name, text, word);
+ completion_list_add_name (tracker,
+ SYMBOL_LANGUAGE (sym),
+ SYMBOL_LINKAGE_NAME (sym),
+ lookup_name, text, word);
+ }
+ }
}
- }
}
/* Field Access */
error_call_unknown_return_type (NULL);
return allocate_value (TYPE_TARGET_TYPE (type));
}
- return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1);
+ return call_function_by_hand (argvec[0], NULL,
+ gdb::make_array_view (argvec + 1,
+ nargs));
case TYPE_CODE_INTERNAL_FUNCTION:
if (noside == EVAL_AVOID_SIDE_EFFECTS)
/* We don't know anything about what the internal
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
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
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);
ada_add_global_exceptions (compiled_regex *preg,
std::vector<ada_exc_info> *exceptions)
{
- struct objfile *objfile;
- struct compunit_symtab *s;
-
/* In Ada, the symbol "search name" is a linkage name, whereas the
regular expression used to do the matching refers to the natural
name. So match against the decoded name. */
NULL,
VARIABLES_DOMAIN);
- ALL_COMPUNITS (objfile, s)
+ for (objfile *objfile : current_program_space->objfiles ())
{
- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (s);
- int i;
-
- for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
+ for (compunit_symtab *s : objfile->compunits ())
{
- struct block *b = BLOCKVECTOR_BLOCK (bv, i);
- struct block_iterator iter;
- struct symbol *sym;
+ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (s);
+ int i;
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- if (ada_is_non_standard_exception_sym (sym)
- && name_matches_regex (SYMBOL_NATURAL_NAME (sym), preg))
- {
- struct ada_exc_info info
- = {SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE_ADDRESS (sym)};
+ for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
+ {
+ struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+ struct block_iterator iter;
+ struct symbol *sym;
- exceptions->push_back (info);
- }
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ if (ada_is_non_standard_exception_sym (sym)
+ && name_matches_regex (SYMBOL_NATURAL_NAME (sym), preg))
+ {
+ struct ada_exc_info info
+ = {SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE_ADDRESS (sym)};
+
+ exceptions->push_back (info);
+ }
+ }
}
}
}
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;
}
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,