/* 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.
}
/* 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;
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;
- int is_scalar;
+ const int is_scalar = is_scalar_type (type);
const int is_big_endian = gdbarch_bits_big_endian (get_type_arch (type));
gdb_byte *staging = NULL;
int staging_len = 0;
type = ada_check_typedef (type);
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_UNION:
- case TYPE_CODE_STRUCT:
- is_scalar = 0;
- break;
- default:
- is_scalar = 1;
- break;
- }
-
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
{
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
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."),