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
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;
gdb_byte *unpacked;
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;
+ std::unique_ptr<gdb_byte[]> staging;
int staging_len = 0;
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
type = ada_check_typedef (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 = (gdb_byte *) malloc (staging_len);
- make_cleanup (xfree, staging);
+ staging.reset (new gdb_byte[staging_len]);
ada_unpack_from_contents (src, bit_offset, bit_size,
- staging, staging_len,
+ staging.get (), staging_len,
is_big_endian, has_negatives (type),
is_scalar);
- type = resolve_dynamic_type (type, staging, 0);
+ 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,
if (bit_size == 0)
{
memset (unpacked, 0, TYPE_LENGTH (type));
- do_cleanups (old_chain);
return v;
}
/* 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, staging_len);
+ 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);
- do_cleanups (old_chain);
return v;
}
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);
}
}
/* 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 = (char *) 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
"a value that is not a record."));
}
-/* Return a string representation of type TYPE. Caller must free
- result. */
+/* Return a string representation of type TYPE. */
-static char *
+static std::string
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);
+ std::string str = ui_file_as_string (tmp_stream);
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;
- type_str = (type != NULL
- ? type_as_string_and_cleanup (type)
- : _("(null)"));
- error (_("Type %s is not a structure or union type"), type_str);
+ 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);
const char *name_str = name != NULL ? name : _("<null>");
error (_("Type %s has no component named %s"),
- type_as_string_and_cleanup (type), name_str);
+ type_as_string (type).c_str (), name_str);
}
return NULL;
(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)
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:
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;
= 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_yyerror,
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 */