/* Ada language support routines for GDB, the GNU debugger.
- Copyright (C) 1992-2015 Free Software Foundation, Inc.
+ Copyright (C) 1992-2016 Free Software Foundation, Inc.
This file is part of GDB.
return xstrdup (ada_decode (encoded));
}
+/* Implement la_sniff_from_mangled_name for Ada. */
+
+static int
+ada_sniff_from_mangled_name (const char *mangled, char **out)
+{
+ const char *demangled = ada_decode (mangled);
+
+ *out = NULL;
+
+ if (demangled != mangled && demangled != NULL && demangled[0] != '<')
+ {
+ /* Set the gsymbol language to Ada, but still return 0.
+ Two reasons for that:
+
+ 1. For Ada, we prefer computing the symbol's decoded name
+ on the fly rather than pre-compute it, in order to save
+ memory (Ada projects are typically very large).
+
+ 2. There are some areas in the definition of the GNAT
+ encoding where, with a bit of bad luck, we might be able
+ to decode a non-Ada symbol, generating an incorrect
+ demangled name (Eg: names ending with "TB" for instance
+ are identified as task bodies and so stripped from
+ the decoded name returned).
+
+ Returning 1, here, but not setting *DEMANGLED, helps us get a
+ little bit of the best of both worlds. Because we're last,
+ we should not affect any of the other languages that were
+ able to demangle the symbol before us; we get to correctly
+ tag Ada symbols as such; and even if we incorrectly tagged a
+ non-Ada symbol, which should be rare, any routing through the
+ Ada language should be transparent (Ada tries to behave much
+ like C/C++ with non-Ada symbols). */
+ return 1;
+ }
+
+ return 0;
+}
+
/* Returns non-zero iff SYM_NAME matches NAME, ignoring any trailing
suffixes that encode debugging information or leading _ada_ on
SYM_NAME (see is_name_suffix commentary for the debugging
}
/* With SRC being a buffer containing BIT_SIZE bits of data at BIT_OFFSET,
- unpack that data into UNPACKED. UNPACKED_LEN is the size in bytes of
+ unpack that data into UNPACKED. UNPACKED_LEN is the size in bytes of
the unpacked buffer.
+ The size of the unpacked buffer (UNPACKED_LEN) is expected to be large
+ enough to contain at least BIT_OFFSET bits. If not, an error is raised.
+
IS_BIG_ENDIAN is nonzero if the data is stored in big endian mode,
zero otherwise.
the indices move. */
int delta = is_big_endian ? -1 : 1;
+ /* Make sure that unpacked is large enough to receive the BIT_SIZE
+ bits from SRC. .*/
+ if ((bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT > unpacked_len)
+ error (_("Cannot unpack %d bits into buffer of %d bytes"),
+ bit_size, unpacked_len);
+
srcBitsLeft = bit_size;
src_bytes_left = src_len;
unpacked_bytes_left = unpacked_len;
accumSize += HOST_CHAR_BIT - unusedLS;
if (accumSize >= HOST_CHAR_BIT)
{
- unpacked[unpacked_idx] = accum & ~(~0L << HOST_CHAR_BIT);
+ unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
accumSize -= HOST_CHAR_BIT;
accum >>= HOST_CHAR_BIT;
unpacked_bytes_left -= 1;
while (unpacked_bytes_left > 0)
{
accum |= sign << accumSize;
- unpacked[unpacked_idx] = accum & ~(~0L << HOST_CHAR_BIT);
+ unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
accumSize -= HOST_CHAR_BIT;
if (accumSize < 0)
accumSize = 0;
struct type *type)
{
struct value *v;
- gdb_byte *src; /* First byte containing data to unpack */
- int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+ const gdb_byte *src; /* First byte containing data to unpack */
gdb_byte *unpacked;
const int is_scalar = is_scalar_type (type);
const int is_big_endian = gdbarch_bits_big_endian (get_type_arch (type));
type = ada_check_typedef (type);
if (obj == NULL)
- src = (gdb_byte *) valaddr + offset;
+ src = valaddr + offset;
else
- src = (gdb_byte *) value_contents (obj) + offset;
+ src = value_contents (obj) + offset;
if (is_dynamic_type (type))
{
we do, is unpack the data into a byte-aligned buffer, and then
use that buffer as our object's value for resolving the type. */
staging_len = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
- staging = malloc (staging_len);
+ staging = (gdb_byte *) malloc (staging_len);
make_cleanup (xfree, staging);
ada_unpack_from_contents (src, bit_offset, bit_size,
is_big_endian, has_negatives (type),
is_scalar);
type = resolve_dynamic_type (type, staging, 0);
+ if (TYPE_LENGTH (type) < (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT)
+ {
+ /* This happens when the length of the object is dynamic,
+ and is actually smaller than the space reserved for it.
+ For instance, in an array of variant records, the bit_size
+ we're given is the array stride, which is constant and
+ normally equal to the maximum size of its element.
+ But, in reality, each element only actually spans a portion
+ of that stride. */
+ bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
+ }
}
if (obj == NULL)
{
v = allocate_value (type);
- src = (gdb_byte *) valaddr + offset;
+ src = valaddr + offset;
}
else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
{
+ int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+ gdb_byte *buf;
+
v = value_at (type, value_address (obj) + offset);
- src = alloca (src_len);
- read_memory (value_address (v), src, src_len);
+ buf = (gdb_byte *) alloca (src_len);
+ read_memory (value_address (v), buf, src_len);
+ src = buf;
}
else
{
v = allocate_value (type);
- src = (gdb_byte *) value_contents (obj) + offset;
+ src = value_contents (obj) + offset;
}
if (obj != NULL)
}
else
set_value_bitsize (v, bit_size);
- unpacked = (gdb_byte *) value_contents (v);
+ unpacked = value_contents_writeable (v);
if (bit_size == 0)
{
}
}
+/* Whether GDB should display formals and return types for functions in the
+ overloads selection menu. */
+static int print_signatures = 1;
+
+/* Print the signature for SYM on STREAM according to the FLAGS options. For
+ all but functions, the signature is just the name of the symbol. For
+ functions, this is the name of the function, the list of types for formals
+ and the return type (if any). */
+
+static void
+ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym,
+ const struct type_print_options *flags)
+{
+ struct type *type = SYMBOL_TYPE (sym);
+
+ fprintf_filtered (stream, "%s", SYMBOL_PRINT_NAME (sym));
+ if (!print_signatures
+ || type == NULL
+ || TYPE_CODE (type) != TYPE_CODE_FUNC)
+ return;
+
+ if (TYPE_NFIELDS (type) > 0)
+ {
+ int i;
+
+ fprintf_filtered (stream, " (");
+ for (i = 0; i < TYPE_NFIELDS (type); ++i)
+ {
+ if (i > 0)
+ fprintf_filtered (stream, "; ");
+ ada_print_type (TYPE_FIELD_TYPE (type, i), NULL, stream, -1, 0,
+ flags);
+ }
+ fprintf_filtered (stream, ")");
+ }
+ if (TYPE_TARGET_TYPE (type) != NULL
+ && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, " return ");
+ ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags);
+ }
+}
+
/* Given a list of NSYMS symbols in SYMS, select up to MAX_RESULTS>0
by asking the user (if necessary), returning the number selected,
and setting the first elements of SYMS items. Error if no symbols
struct symtab_and_line sal =
find_function_start_sal (syms[i].symbol, 1);
+ printf_unfiltered ("[%d] ", i + first_choice);
+ ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
+ &type_print_raw_options);
if (sal.symtab == NULL)
- printf_unfiltered (_("[%d] %s at <no source file available>:%d\n"),
- i + first_choice,
- SYMBOL_PRINT_NAME (syms[i].symbol),
+ printf_unfiltered (_(" at <no source file available>:%d\n"),
sal.line);
else
- printf_unfiltered (_("[%d] %s at %s:%d\n"), i + first_choice,
- SYMBOL_PRINT_NAME (syms[i].symbol),
+ printf_unfiltered (_(" at %s:%d\n"),
symtab_to_filename_for_display (sal.symtab),
sal.line);
continue;
symtab = symbol_symtab (syms[i].symbol);
if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL)
- printf_unfiltered (_("[%d] %s at %s:%d\n"),
- i + first_choice,
- SYMBOL_PRINT_NAME (syms[i].symbol),
- symtab_to_filename_for_display (symtab),
- SYMBOL_LINE (syms[i].symbol));
+ {
+ printf_unfiltered ("[%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));
+ }
else if (is_enumeral
&& TYPE_NAME (SYMBOL_TYPE (syms[i].symbol)) != NULL)
{
printf_unfiltered (_("'(%s) (enumeral)\n"),
SYMBOL_PRINT_NAME (syms[i].symbol));
}
- else if (symtab != NULL)
- printf_unfiltered (is_enumeral
- ? _("[%d] %s in %s (enumeral)\n")
- : _("[%d] %s at %s:?\n"),
- i + first_choice,
- SYMBOL_PRINT_NAME (syms[i].symbol),
- symtab_to_filename_for_display (symtab));
- else
- printf_unfiltered (is_enumeral
- ? _("[%d] %s (enumeral)\n")
- : _("[%d] %s at ?\n"),
- i + first_choice,
- SYMBOL_PRINT_NAME (syms[i].symbol));
+ else
+ {
+ printf_unfiltered ("[%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));
+ else
+ printf_unfiltered (is_enumeral
+ ? _(" (enumeral)\n")
+ : _(" at ?\n"));
+ }
}
}
{
const char *name = TYPE_FIELD_NAME (type, field_num);
+ if (name != NULL && strcmp (name, "RETVAL") == 0)
+ {
+ /* This happens in functions with "out" or "in out" parameters
+ which are passed by copy. For such functions, GNAT describes
+ the function's return type as being a struct where the return
+ value is in a field called RETVAL, and where the other "out"
+ or "in out" parameters are fields of that struct. This is not
+ a wrapper. */
+ return 0;
+ }
+
return (name != NULL
&& (startswith (name, "PARENT")
|| strcmp (name, "REP") == 0
"a value that is not a record."));
}
+/* Return a string representation of type TYPE. Caller must free
+ result. */
+
+static char *
+type_as_string (struct type *type)
+{
+ struct ui_file *tmp_stream = mem_fileopen ();
+ struct cleanup *old_chain;
+ char *str;
+
+ tmp_stream = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (tmp_stream);
+
+ type_print (type, "", tmp_stream, -1);
+ str = ui_file_xstrdup (tmp_stream, NULL);
+
+ do_cleanups (old_chain);
+ return str;
+}
+
+/* Return a string representation of type TYPE, and install a cleanup
+ that releases it. */
+
+static char *
+type_as_string_and_cleanup (struct type *type)
+{
+ char *str;
+
+ str = type_as_string (type);
+ make_cleanup (xfree, str);
+ return str;
+}
+
/* Given a type TYPE, look up the type of the component of type named NAME.
If DISPP is non-null, add its byte displacement from the beginning of a
structure (pointed to by a value) of type TYPE to *DISPP (does not
|| (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION))
{
+ const char *type_str;
+
if (noerr)
return NULL;
- else
- {
- target_terminal_ours ();
- gdb_flush (gdb_stdout);
- if (type == NULL)
- error (_("Type (null) is not a structure or union type"));
- else
- {
- /* XXX: type_sprint */
- fprintf_unfiltered (gdb_stderr, _("Type "));
- type_print (type, "", gdb_stderr, -1);
- error (_(" is not a structure or union type"));
- }
- }
+
+ type_str = (type != NULL
+ ? type_as_string_and_cleanup (type)
+ : _("(null)"));
+ error (_("Type %s is not a structure or union type"), type_str);
}
type = to_static_fixed_type (type);
BadName:
if (!noerr)
{
- target_terminal_ours ();
- gdb_flush (gdb_stdout);
- if (name == NULL)
- {
- /* XXX: type_sprint */
- fprintf_unfiltered (gdb_stderr, _("Type "));
- type_print (type, "", gdb_stderr, -1);
- error (_(" has no component named <null>"));
- }
- else
- {
- /* XXX: type_sprint */
- fprintf_unfiltered (gdb_stderr, _("Type "));
- type_print (type, "", gdb_stderr, -1);
- error (_(" has no component named %s"), name);
- }
+ const char *name_str = name != NULL ? name : _("<null>");
+
+ error (_("Type %s has no component named %s"),
+ type_as_string_and_cleanup (type), name_str);
}
return NULL;
{
static char *result;
static size_t result_len = 0;
- char *tmp;
+ const char *tmp;
/* First, unqualify the enumeration name:
1. Search for the last '.' character. If we find one, then skip
return value_zero (ada_aligned_type (type), lval_memory);
}
else
- arg1 = ada_value_struct_elt (arg1, &exp->elts[pc + 2].string, 0);
- arg1 = unwrap_value (arg1);
- return ada_to_fixed_value (arg1);
+ {
+ arg1 = ada_value_struct_elt (arg1, &exp->elts[pc + 2].string, 0);
+ arg1 = unwrap_value (arg1);
+ return ada_to_fixed_value (arg1);
+ }
case OP_TYPE:
/* The value is not supposed to be used. This is here to make it
(of any type), return the address in inferior memory where the name
of the exception is stored, if applicable.
+ Assumes the selected frame is the current frame.
+
Return zero if the address could not be computed, or if not relevant. */
static CORE_ADDR
ui_out_field_int (uiout, "bkptno", b->number);
ui_out_text (uiout, ", ");
+ /* ada_exception_name_addr relies on the selected frame being the
+ current frame. Need to do this here because this function may be
+ called more than once when printing a stop, and below, we'll
+ select the first frame past the Ada run-time (see
+ ada_find_printable_frame). */
+ select_frame (get_current_frame ());
+
switch (ex)
{
case ada_catch_exception:
= arch_character_type (gdbarch, TARGET_CHAR_BIT, 0, "character");
lai->primitive_type_vector [ada_primitive_type_float]
= arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
- "float", NULL);
+ "float", gdbarch_float_format (gdbarch));
lai->primitive_type_vector [ada_primitive_type_double]
= arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
- "long_float", NULL);
+ "long_float", gdbarch_double_format (gdbarch));
lai->primitive_type_vector [ada_primitive_type_long_long]
= arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch),
0, "long_long_integer");
lai->primitive_type_vector [ada_primitive_type_long_double]
- = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
- "long_long_float", NULL);
+ = arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
+ "long_long_float", gdbarch_long_double_format (gdbarch));
lai->primitive_type_vector [ada_primitive_type_natural]
= arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
0, "natural");
return default_read_var_value (var, var_block, frame);
}
+static const char *ada_extensions[] =
+{
+ ".adb", ".ads", ".a", ".ada", ".dg", NULL
+};
+
const struct language_defn ada_language_defn = {
"ada", /* Language name */
"Ada",
that's not quite what this means. */
array_row_major,
macro_expansion_no,
+ ada_extensions,
&ada_exp_descriptor,
parse,
- ada_error,
+ ada_yyerror,
resolve,
ada_printchar, /* Print a character constant */
ada_printstr, /* Function to print string constant */
ada_lookup_symbol_nonlocal, /* Looking up non-local symbols. */
basic_lookup_transparent_type, /* lookup_transparent_type */
ada_la_decode, /* Language specific symbol demangler */
+ ada_sniff_from_mangled_name,
NULL, /* Language specific
class_name_from_physname */
ada_op_print_tab, /* expression operators for printing */
this option to \"off\" unless necessary."),
NULL, NULL, &set_ada_list, &show_ada_list);
+ add_setshow_boolean_cmd ("print-signatures", class_vars,
+ &print_signatures, _("\
+Enable or disable the output of formal and return types for functions in the \
+overloads selection menu"), _("\
+Show whether the output of formal and return types for functions in the \
+overloads selection menu is activated"),
+ NULL, NULL, NULL, &set_ada_list, &show_ada_list);
+
add_catch_command ("exception", _("\
Catch Ada exceptions, when raised.\n\
With an argument, catch only exceptions with the given name."),