/* Ada language support routines for GDB, the GNU debugger.
- Copyright (C) 1992-2015 Free Software Foundation, Inc.
+ Copyright (C) 1992-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "mi/mi-common.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
+#include "common/function-view.h"
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C).
{
struct ada_inferior_data *data;
- data = inferior_data (inf, ada_inferior_data);
+ data = (struct ada_inferior_data *) inferior_data (inf, ada_inferior_data);
if (data != NULL)
xfree (data);
}
{
struct ada_inferior_data *data;
- data = inferior_data (inf, ada_inferior_data);
+ data = (struct ada_inferior_data *) inferior_data (inf, ada_inferior_data);
if (data == NULL)
{
data = XCNEW (struct ada_inferior_data);
{
struct ada_pspace_data *data;
- data = program_space_data (pspace, ada_pspace_data_handle);
+ data = ((struct ada_pspace_data *)
+ program_space_data (pspace, ada_pspace_data_handle));
if (data == NULL)
{
data = XCNEW (struct ada_pspace_data);
static void
ada_pspace_data_cleanup (struct program_space *pspace, void *data)
{
- struct ada_pspace_data *pspace_data = data;
+ struct ada_pspace_data *pspace_data = (struct ada_pspace_data *) data;
if (pspace_data->sym_cache != NULL)
ada_free_symbol_cache (pspace_data->sym_cache);
{
struct general_symbol_info *gsymbol = (struct general_symbol_info *) arg;
const char **resultp =
- &gsymbol->language_specific.mangled_lang.demangled_name;
+ &gsymbol->language_specific.demangled_name;
if (!gsymbol->ada_mangled)
{
gsymbol->ada_mangled = 1;
if (obstack != NULL)
- *resultp = obstack_copy0 (obstack, decoded, strlen (decoded));
+ *resultp
+ = (const char *) obstack_copy0 (obstack, decoded, strlen (decoded));
else
{
/* Sometimes, we can't find a corresponding objfile, in
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
+ the unpacked buffer.
-/* Create a new value of type TYPE from the contents of OBJ starting
- at byte OFFSET, and bit offset BIT_OFFSET within that byte,
- proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then
- assigning through the result will set the field fetched from.
- VALADDR is ignored unless OBJ is NULL, in which case,
- VALADDR+OFFSET must address the start of storage containing the
- packed value. The value returned in this case is never an lval.
- Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */
+ 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.
-struct value *
-ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
- long offset, int bit_offset, int bit_size,
- struct type *type)
-{
- struct value *v;
- int src, /* Index into the source area */
- targ, /* Index into the target area */
- srcBitsLeft, /* Number of source bits left to move */
- nsrc, ntarg, /* Number of source and target bytes */
- unusedLS, /* Number of bits in next significant
+ IS_BIG_ENDIAN is nonzero if the data is stored in big endian mode,
+ zero otherwise.
+
+ IS_SIGNED_TYPE is nonzero if the data corresponds to a signed type.
+
+ IS_SCALAR is nonzero if the data corresponds to a signed type. */
+
+static void
+ada_unpack_from_contents (const gdb_byte *src, int bit_offset, int bit_size,
+ gdb_byte *unpacked, int unpacked_len,
+ int is_big_endian, int is_signed_type,
+ int is_scalar)
+{
+ int src_len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+ int src_idx; /* Index into the source area */
+ int src_bytes_left; /* Number of source bytes left to process. */
+ int srcBitsLeft; /* Number of source bits left to move */
+ int unusedLS; /* Number of bits in next significant
byte of source that are unused */
- accumSize; /* Number of meaningful bits in accum */
- unsigned char *bytes; /* First byte containing data to unpack */
- unsigned char *unpacked;
+
+ int unpacked_idx; /* Index into the unpacked buffer */
+ int unpacked_bytes_left; /* Number of bytes left to set in unpacked. */
+
unsigned long accum; /* Staging area for bits being transferred */
+ int accumSize; /* Number of meaningful bits in accum */
unsigned char sign;
- int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
+
/* Transmit bytes from least to most significant; delta is the direction
the indices move. */
- int delta = gdbarch_bits_big_endian (get_type_arch (type)) ? -1 : 1;
+ int delta = is_big_endian ? -1 : 1;
- type = ada_check_typedef (type);
-
- if (obj == NULL)
- {
- v = allocate_value (type);
- bytes = (unsigned char *) (valaddr + offset);
- }
- else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
- {
- v = value_at (type, value_address (obj) + offset);
- type = value_type (v);
- if (TYPE_LENGTH (type) * HOST_CHAR_BIT < bit_size)
- {
- /* This can happen in the case of an array of dynamic objects,
- where the size of each element changes from element to element.
- In that case, we're initially given the array stride, but
- after resolving the element type, we find that its size is
- less than this stride. In that case, adjust bit_size to
- match TYPE's length, and recompute LEN accordingly. */
- bit_size = TYPE_LENGTH (type) * HOST_CHAR_BIT;
- len = TYPE_LENGTH (type) + (bit_offset + HOST_CHAR_BIT - 1) / 8;
- }
- bytes = (unsigned char *) alloca (len);
- read_memory (value_address (v), bytes, len);
- }
- else
- {
- v = allocate_value (type);
- bytes = (unsigned char *) value_contents (obj) + offset;
- }
-
- if (obj != NULL)
- {
- long new_offset = offset;
-
- set_value_component_location (v, obj);
- set_value_bitpos (v, bit_offset + value_bitpos (obj));
- set_value_bitsize (v, bit_size);
- if (value_bitpos (v) >= HOST_CHAR_BIT)
- {
- ++new_offset;
- set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
- }
- set_value_offset (v, new_offset);
-
- /* Also set the parent value. This is needed when trying to
- assign a new value (in inferior memory). */
- set_value_parent (v, obj);
- }
- else
- set_value_bitsize (v, bit_size);
- unpacked = (unsigned char *) value_contents (v);
+ /* 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;
- nsrc = len;
- ntarg = TYPE_LENGTH (type);
+ src_bytes_left = src_len;
+ unpacked_bytes_left = unpacked_len;
sign = 0;
- if (bit_size == 0)
- {
- memset (unpacked, 0, TYPE_LENGTH (type));
- return v;
- }
- else if (gdbarch_bits_big_endian (get_type_arch (type)))
+
+ if (is_big_endian)
{
- src = len - 1;
- if (has_negatives (type)
- && ((bytes[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
+ src_idx = src_len - 1;
+ if (is_signed_type
+ && ((src[0] << bit_offset) & (1 << (HOST_CHAR_BIT - 1))))
sign = ~0;
unusedLS =
(HOST_CHAR_BIT - (bit_size + bit_offset) % HOST_CHAR_BIT)
% HOST_CHAR_BIT;
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_UNION:
- case TYPE_CODE_STRUCT:
+ if (is_scalar)
+ {
+ accumSize = 0;
+ unpacked_idx = unpacked_len - 1;
+ }
+ else
+ {
/* Non-scalar values must be aligned at a byte boundary... */
accumSize =
(HOST_CHAR_BIT - bit_size % HOST_CHAR_BIT) % HOST_CHAR_BIT;
/* ... And are placed at the beginning (most-significant) bytes
of the target. */
- targ = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1;
- ntarg = targ + 1;
- break;
- default:
- accumSize = 0;
- targ = TYPE_LENGTH (type) - 1;
- break;
- }
+ unpacked_idx = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT - 1;
+ unpacked_bytes_left = unpacked_idx + 1;
+ }
}
else
{
int sign_bit_offset = (bit_size + bit_offset - 1) % 8;
- src = targ = 0;
+ src_idx = unpacked_idx = 0;
unusedLS = bit_offset;
accumSize = 0;
- if (has_negatives (type) && (bytes[len - 1] & (1 << sign_bit_offset)))
+ if (is_signed_type && (src[src_len - 1] & (1 << sign_bit_offset)))
sign = ~0;
}
accum = 0;
- while (nsrc > 0)
+ while (src_bytes_left > 0)
{
/* Mask for removing bits of the next source byte that are not
part of the value. */
unsigned int signMask = sign & ~unusedMSMask;
accum |=
- (((bytes[src] >> unusedLS) & unusedMSMask) | signMask) << accumSize;
+ (((src[src_idx] >> unusedLS) & unusedMSMask) | signMask) << accumSize;
accumSize += HOST_CHAR_BIT - unusedLS;
if (accumSize >= HOST_CHAR_BIT)
{
- unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT);
+ unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
accumSize -= HOST_CHAR_BIT;
accum >>= HOST_CHAR_BIT;
- ntarg -= 1;
- targ += delta;
+ unpacked_bytes_left -= 1;
+ unpacked_idx += delta;
}
srcBitsLeft -= HOST_CHAR_BIT - unusedLS;
unusedLS = 0;
- nsrc -= 1;
- src += delta;
+ src_bytes_left -= 1;
+ src_idx += delta;
}
- while (ntarg > 0)
+ while (unpacked_bytes_left > 0)
{
accum |= sign << accumSize;
- unpacked[targ] = accum & ~(~0L << HOST_CHAR_BIT);
+ unpacked[unpacked_idx] = accum & ~(~0UL << HOST_CHAR_BIT);
accumSize -= HOST_CHAR_BIT;
if (accumSize < 0)
accumSize = 0;
accum >>= HOST_CHAR_BIT;
- ntarg -= 1;
- targ += delta;
+ unpacked_bytes_left -= 1;
+ unpacked_idx += delta;
+ }
+}
+
+/* Create a new value of type TYPE from the contents of OBJ starting
+ at byte OFFSET, and bit offset BIT_OFFSET within that byte,
+ proceeding for BIT_SIZE bits. If OBJ is an lval in memory, then
+ assigning through the result will set the field fetched from.
+ VALADDR is ignored unless OBJ is NULL, in which case,
+ VALADDR+OFFSET must address the start of storage containing the
+ packed value. The value returned in this case is never an lval.
+ Assumes 0 <= BIT_OFFSET < HOST_CHAR_BIT. */
+
+struct value *
+ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
+ long offset, int bit_offset, int bit_size,
+ struct type *type)
+{
+ struct value *v;
+ 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));
+ std::unique_ptr<gdb_byte[]> staging;
+ int staging_len = 0;
+
+ type = ada_check_typedef (type);
+
+ if (obj == NULL)
+ src = valaddr + offset;
+ else
+ src = value_contents (obj) + offset;
+
+ if (is_dynamic_type (type))
+ {
+ /* The length of TYPE might by dynamic, so we need to resolve
+ TYPE in order to know its actual size, which we then use
+ to create the contents buffer of the value we return.
+ The difficulty is that the data containing our object is
+ packed, and therefore maybe not at a byte boundary. So, what
+ 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.reset (new gdb_byte[staging_len]);
+
+ ada_unpack_from_contents (src, bit_offset, bit_size,
+ staging.get (), staging_len,
+ is_big_endian, has_negatives (type),
+ is_scalar);
+ type = resolve_dynamic_type (type, staging.get (), 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 = 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);
+ buf = (gdb_byte *) alloca (src_len);
+ read_memory (value_address (v), buf, src_len);
+ src = buf;
+ }
+ else
+ {
+ v = allocate_value (type);
+ src = value_contents (obj) + offset;
+ }
+
+ if (obj != NULL)
+ {
+ long new_offset = offset;
+
+ set_value_component_location (v, obj);
+ set_value_bitpos (v, bit_offset + value_bitpos (obj));
+ set_value_bitsize (v, bit_size);
+ if (value_bitpos (v) >= HOST_CHAR_BIT)
+ {
+ ++new_offset;
+ set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
+ }
+ set_value_offset (v, new_offset);
+
+ /* Also set the parent value. This is needed when trying to
+ assign a new value (in inferior memory). */
+ set_value_parent (v, obj);
+ }
+ else
+ set_value_bitsize (v, bit_size);
+ unpacked = value_contents_writeable (v);
+
+ if (bit_size == 0)
+ {
+ memset (unpacked, 0, TYPE_LENGTH (type));
+ return v;
+ }
+
+ if (staging != NULL && staging_len == TYPE_LENGTH (type))
+ {
+ /* Small short-cut: If we've unpacked the data into a buffer
+ of the same size as TYPE's length, then we can reuse that,
+ instead of doing the unpacking again. */
+ memcpy (unpacked, staging.get (), staging_len);
+ }
+ else
+ ada_unpack_from_contents (src, bit_offset, bit_size,
+ unpacked, TYPE_LENGTH (type),
+ is_big_endian, has_negatives (type), is_scalar);
- if (is_dynamic_type (value_type (v)))
- v = value_from_contents_and_address (value_type (v), value_contents (v),
- 0);
return v;
}
int len = (value_bitpos (toval)
+ bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
int from_size;
- gdb_byte *buffer = alloca (len);
+ gdb_byte *buffer = (gdb_byte *) alloca (len);
struct value *val;
CORE_ADDR to_addr = value_address (toval);
/* Assuming ARR is a pointer to a GDB array, the value of the element
of *ARR at the ARITY indices given in IND.
- Does not read the entire array into memory. */
+ Does not read the entire array into memory.
+
+ Note: Unlike what one would expect, this function is used instead of
+ ada_value_subscript for basically all non-packed array types. The reason
+ for this is that a side effect of doing our own pointer arithmetics instead
+ of relying on value_subscript is that there is no implicit typedef peeling.
+ This is important for arrays of array accesses, where it allows us to
+ preserve the fact that the array's element is an array access, where the
+ access part os encoded in a typedef layer. */
static struct value *
ada_value_ptr_subscript (struct value *arr, int arity, struct value **ind)
{
int k;
+ struct value *array_ind = ada_value_ind (arr);
struct type *type
- = check_typedef (value_enclosing_type (ada_value_ind (arr)));
+ = check_typedef (value_enclosing_type (array_ind));
+
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && TYPE_FIELD_BITSIZE (type, 0) > 0)
+ return value_subscript_packed (array_ind, arity, ind);
for (k = 0; k < arity; k += 1)
{
}
}
+/* 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 struct block *block)
{
const char *sym_name;
- struct expression *expr;
- struct value *value;
- struct cleanup *old_chain = NULL;
sym_name = SYMBOL_LINKAGE_NAME (renaming_sym);
- expr = parse_exp_1 (&sym_name, 0, block, 0);
- old_chain = make_cleanup (free_current_contents, &expr);
- value = evaluate_expression (expr);
-
- do_cleanups (old_chain);
- return value;
+ expression_up expr = parse_exp_1 (&sym_name, 0, block, 0);
+ return evaluate_expression (expr.get ());
}
\f
const CORE_ADDR addr =
value_as_long (value_allocate_space_in_inferior (len));
- set_value_address (val, addr);
VALUE_LVAL (val) = lval_memory;
+ set_value_address (val, addr);
write_memory (addr, value_contents (val), len);
}
{
struct gdbarch *gdbarch = get_type_arch (type);
unsigned len = TYPE_LENGTH (type);
- gdb_byte *buf = alloca (len);
+ gdb_byte *buf = (gdb_byte *) alloca (len);
CORE_ADDR addr;
addr = value_address (value);
sizeof (*e));
e->next = sym_cache->root[h];
sym_cache->root[h] = e;
- e->name = copy = obstack_alloc (&sym_cache->cache_space, strlen (name) + 1);
+ e->name = copy
+ = (char *) obstack_alloc (&sym_cache->cache_space, strlen (name) + 1);
strcpy (copy, name);
e->sym = sym;
e->domain = domain;
defns_collected (struct obstack *obstackp, int finish)
{
if (finish)
- return obstack_finish (obstackp);
+ return (struct block_symbol *) obstack_finish (obstackp);
else
return (struct block_symbol *) obstack_base (obstackp);
}
{
ALL_OBJFILES (objfile)
{
- char *name1 = alloca (strlen (name) + sizeof ("_ada_"));
+ char *name1 = (char *) alloca (strlen (name) + sizeof ("_ada_"));
strcpy (name1, "_ada_");
strcpy (name1 + sizeof ("_ada_") - 1, name);
data.objfile = objfile;
/* 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)
+ada_iterate_over_symbols
+ (const struct block *block, const char *name, domain_enum domain,
+ gdb::function_view<symbol_found_callback_ftype> callback)
{
int ndefs, i;
struct block_symbol *results;
ndefs = ada_lookup_symbol_list_worker (name, block, domain, &results, 0);
for (i = 0; i < ndefs; ++i)
{
- if (! (*callback) (results[i].symbol, data))
+ if (!callback (results[i].symbol))
break;
}
}
/* 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.
+ be used to look that entity up in Ada units.
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 *
+std::string
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';
- }
+ return std::string (name + 1, nlen - 2);
else
- canon = xstrdup (ada_encode (ada_fold_name (name)));
- return canon;
+ return ada_encode (ada_fold_name (name));
}
/* The result is as for ada_lookup_symbol_list with FULL_SEARCH set
if (word == orig_text)
{
- completion = xmalloc (strlen (match) + 5);
+ completion = (char *) xmalloc (strlen (match) + 5);
strcpy (completion, match);
}
else if (word > orig_text)
{
/* Return some portion of sym_name. */
- completion = xmalloc (strlen (match) + 5);
+ completion = (char *) xmalloc (strlen (match) + 5);
strcpy (completion, match + (word - orig_text));
}
else
{
/* Return some of ORIG_TEXT plus sym_name. */
- completion = xmalloc (strlen (match) + (orig_text - word) + 5);
+ completion = (char *) xmalloc (strlen (match) + (orig_text - word) + 5);
strncpy (completion, word, orig_text - word);
completion[orig_text - word] = '\0';
strcat (completion, match);
VEC_safe_push (char_ptr, *sv, completion);
}
-/* An object of this type is passed as the user_data argument to the
- expand_symtabs_matching method. */
-struct add_partial_datum
-{
- VEC(char_ptr) **completions;
- const char *text;
- int text_len;
- const char *text0;
- const char *word;
- int wild_match;
- int encoded;
-};
-
-/* A callback for expand_symtabs_matching. */
-
-static int
-ada_complete_symbol_matcher (const char *name, void *user_data)
-{
- struct add_partial_datum *data = user_data;
-
- return symbol_completion_match (name, data->text, data->text_len,
- data->wild_match, data->encoded) != NULL;
-}
-
/* Return a list of possible symbol names completing TEXT0. WORD is
the entire command on which completion is made. */
}
/* First, look at the partial symtab symbols. */
- {
- struct add_partial_datum data;
-
- data.completions = &completions;
- data.text = text;
- data.text_len = text_len;
- data.text0 = text0;
- data.word = word;
- data.wild_match = wild_match_p;
- data.encoded = encoded_p;
- expand_symtabs_matching (NULL, ada_complete_symbol_matcher, NULL,
- ALL_DOMAIN, &data);
- }
+ expand_symtabs_matching (NULL,
+ [&] (const char *symname)
+ {
+ return symbol_completion_match (symname,
+ text, text_len,
+ wild_match_p,
+ encoded_p);
+ },
+ NULL,
+ ALL_DOMAIN);
/* At this point scan through the misc symbol vectors and add each
symbol you find to the list. Eventually we want to ignore
{
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. */
+
+static std::string
+type_as_string (struct type *type)
+{
+ string_file tmp_stream;
+
+ type_print (type, "", &tmp_stream, -1);
+
+ return std::move (tmp_stream.string ());
+}
+
/* 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
{
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"));
- }
- }
+
+ error (_("Type %s is not a structure or union type"),
+ type != NULL ? type_as_string (type).c_str () : _("(null)"));
}
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 (type).c_str (), name_str);
}
return NULL;
else if (ada_type_name (fixed_record_type) != NULL)
{
const char *name = ada_type_name (fixed_record_type);
- char *xvz_name = alloca (strlen (name) + 7 /* "___XVZ\0" */);
+ char *xvz_name
+ = (char *) alloca (strlen (name) + 7 /* "___XVZ\0" */);
int xvz_found = 0;
LONGEST size;
{
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
should return a ref as it should be valid to ask
for its address; so rebuild a ref after coerce. */
arg1 = ada_coerce_ref (arg1);
- return value_ref (arg1);
+ return value_ref (arg1, TYPE_CODE_REF);
}
}
therefore already coerced to a simple array. Nothing further
to do. */
;
- else if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_REF
- || (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_ARRAY
- && VALUE_LVAL (argvec[0]) == lval_memory))
- argvec[0] = value_addr (argvec[0]);
+ else if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_REF)
+ {
+ /* Make sure we dereference references so that all the code below
+ feels like it's really handling the referenced value. Wrapping
+ types (for alignment) may be there, so make sure we strip them as
+ well. */
+ argvec[0] = ada_to_fixed_value (coerce_ref (argvec[0]));
+ }
+ else if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_ARRAY
+ && VALUE_LVAL (argvec[0]) == lval_memory)
+ argvec[0] = value_addr (argvec[0]);
type = ada_check_typedef (value_type (argvec[0]));
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
/* The condition that checks whether the exception that was raised
is the specific exception the user specified on catchpoint
creation. */
- struct expression *excep_cond_expr;
+ expression_up excep_cond_expr;
};
/* Implement the DTOR method in the bp_location_ops structure for all
{
struct ada_catchpoint_location *al = (struct ada_catchpoint_location *) bl;
- xfree (al->excep_cond_expr);
+ al->excep_cond_expr.reset ();
}
/* The vtable to be used in Ada catchpoint locations. */
{
struct ada_catchpoint_location *ada_loc
= (struct ada_catchpoint_location *) bl;
- struct expression *exp = NULL;
+ expression_up exp;
if (!bl->shlib_disabled)
{
TRY
{
exp = parse_exp_1 (&s, bl->address,
- block_for_pc (bl->address), 0);
+ block_for_pc (bl->address),
+ 0);
}
CATCH (e, RETURN_MASK_ERROR)
{
warning (_("failed to reevaluate internal exception condition "
"for catchpoint %d: %s"),
c->base.number, e.message);
- /* There is a bug in GCC on sparc-solaris when building with
- optimization which causes EXP to change unexpectedly
- (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56982).
- The problem should be fixed starting with GCC 4.9.
- In the meantime, work around it by forcing EXP back
- to NULL. */
- exp = NULL;
}
END_CATCH
}
- ada_loc->excep_cond_expr = exp;
+ ada_loc->excep_cond_expr = std::move (exp);
}
do_cleanups (old_chain);
{
struct ada_catchpoint_location *loc;
- loc = XNEW (struct ada_catchpoint_location);
+ loc = new ada_catchpoint_location ();
init_bp_location (&loc->base, &ada_catchpoint_location_ops, self);
loc->excep_cond_expr = NULL;
return &loc->base;
struct value *mark;
mark = value_mark ();
- stop = value_true (evaluate_expression (ada_loc->excep_cond_expr));
+ stop = value_true (evaluate_expression (ada_loc->excep_cond_expr.get ()));
value_free_to_mark (mark);
}
CATCH (ex, RETURN_MASK_ALL)
annotate_catchpoint (b->number);
- if (ui_out_is_mi_like_p (uiout))
+ if (uiout->is_mi_like_p ())
{
- ui_out_field_string (uiout, "reason",
+ uiout->field_string ("reason",
async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+ uiout->field_string ("disp", bpdisp_text (b->disposition));
}
- ui_out_text (uiout,
- b->disposition == disp_del ? "\nTemporary catchpoint "
- : "\nCatchpoint ");
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, ", ");
+ uiout->text (b->disposition == disp_del
+ ? "\nTemporary catchpoint " : "\nCatchpoint ");
+ uiout->field_int ("bkptno", b->number);
+ uiout->text (", ");
+
+ /* 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)
{
hit. We used ui_out_text to make sure that this extra
info does not pollute the exception name in the MI case. */
if (ex == ada_catch_exception_unhandled)
- ui_out_text (uiout, "unhandled ");
- ui_out_field_string (uiout, "exception-name", exception_name);
+ uiout->text ("unhandled ");
+ uiout->field_string ("exception-name", exception_name);
}
break;
case ada_catch_assert:
that his program just hit an assertion-failure catchpoint.
We used ui_out_text because this info does not belong in
the MI output. */
- ui_out_text (uiout, "failed assertion");
+ uiout->text ("failed assertion");
break;
}
- ui_out_text (uiout, " at ");
+ uiout->text (" at ");
ada_find_printable_frame (get_current_frame ());
return PRINT_SRC_AND_LOC;
if (opts.addressprint)
{
annotate_field (4);
- ui_out_field_core_addr (uiout, "addr", b->loc->gdbarch, b->loc->address);
+ uiout->field_core_addr ("addr", b->loc->gdbarch, b->loc->address);
}
annotate_field (5);
{
char *msg = xstrprintf (_("`%s' Ada exception"), c->excep_string);
- ui_out_field_string (uiout, "what", msg);
+ uiout->field_string ("what", msg);
xfree (msg);
}
else
- ui_out_field_string (uiout, "what", "all Ada exceptions");
+ uiout->field_string ("what", "all Ada exceptions");
break;
case ada_catch_exception_unhandled:
- ui_out_field_string (uiout, "what", "unhandled Ada exceptions");
+ uiout->field_string ("what", "unhandled Ada exceptions");
break;
case ada_catch_assert:
- ui_out_field_string (uiout, "what", "failed Ada assertions");
+ uiout->field_string ("what", "failed Ada assertions");
break;
default:
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
struct ui_out *uiout = current_uiout;
- ui_out_text (uiout, b->disposition == disp_del ? _("Temporary catchpoint ")
+ uiout->text (b->disposition == disp_del ? _("Temporary catchpoint ")
: _("Catchpoint "));
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, ": ");
+ uiout->field_int ("bkptno", b->number);
+ uiout->text (": ");
switch (ex)
{
char *info = xstrprintf (_("`%s' Ada exception"), c->excep_string);
struct cleanup *old_chain = make_cleanup (xfree, info);
- ui_out_text (uiout, info);
+ uiout->text (info);
do_cleanups (old_chain);
}
else
- ui_out_text (uiout, _("all Ada exceptions"));
+ uiout->text (_("all Ada exceptions"));
break;
case ada_catch_exception_unhandled:
- ui_out_text (uiout, _("unhandled Ada exceptions"));
+ uiout->text (_("unhandled Ada exceptions"));
break;
case ada_catch_assert:
- ui_out_text (uiout, _("failed Ada assertions"));
+ uiout->text (_("failed Ada assertions"));
break;
default:
/* Make a copy of the current argument and return it. */
- result = xmalloc (end - args + 1);
+ result = (char *) xmalloc (end - args + 1);
strncpy (result, args, end - args);
result[end - args] = '\0';
struct symtab_and_line sal
= ada_exception_sal (ex_kind, excep_string, &addr_string, &ops);
- c = XNEW (struct ada_catchpoint);
+ c = new ada_catchpoint ();
init_ada_exception_breakpoint (&c->base, gdbarch, sal, addr_string,
ops, tempflag, disabled, from_tty);
c->excep_string = excep_string;
VEC_truncate(ada_exc_info, *exceptions, skip + to_sort_len);
}
-/* A function intended as the "name_matcher" callback in the struct
- quick_symbol_functions' expand_symtabs_matching method.
-
- SEARCH_NAME is the symbol's search name.
-
- If USER_DATA is not NULL, it is a pointer to a regext_t object
- used to match the symbol (by natural name). Otherwise, when USER_DATA
- is null, no filtering is performed, and all symbols are a positive
- match. */
-
-static int
-ada_exc_search_name_matches (const char *search_name, void *user_data)
-{
- regex_t *preg = user_data;
-
- if (preg == NULL)
- return 1;
-
- /* 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. */
- return (regexec (preg, ada_decode (search_name), 0, NULL, 0) == 0);
-}
-
/* Add all exceptions defined by the Ada standard whose name match
a regular expression.
}
}
+/* Return true if NAME matches PREG or if PREG is NULL. */
+
+static bool
+name_matches_regex (const char *name, regex_t *preg)
+{
+ return (preg == NULL
+ || regexec (preg, ada_decode (name), 0, NULL, 0) == 0);
+}
+
/* Add all exceptions defined globally whose name name match
a regular expression, excluding standard exceptions.
struct objfile *objfile;
struct compunit_symtab *s;
- expand_symtabs_matching (NULL, ada_exc_search_name_matches, NULL,
- VARIABLES_DOMAIN, preg);
+ /* 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. */
+ expand_symtabs_matching (NULL,
+ [&] (const char *search_name)
+ {
+ const char *decoded = ada_decode (search_name);
+ return name_matches_regex (decoded, preg);
+ },
+ NULL,
+ VARIABLES_DOMAIN);
ALL_COMPUNITS (objfile, s)
{
ALL_BLOCK_SYMBOLS (b, iter, sym)
if (ada_is_non_standard_exception_sym (sym)
- && (preg == NULL
- || regexec (preg, SYMBOL_NATURAL_NAME (sym),
- 0, NULL, 0) == 0))
+ && name_matches_regex (SYMBOL_NATURAL_NAME (sym), preg))
{
struct ada_exc_info info
= {SYMBOL_PRINT_NAME (sym), SYMBOL_VALUE_ADDRESS (sym)};
= 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."),