return result;
}
-/* Return a string starting with '<', followed by STR, and '>'.
- The result is good until the next call. */
+/* Return a string starting with '<', followed by STR, and '>'. */
-static char *
+static std::string
add_angle_brackets (const char *str)
{
- static char *result = NULL;
-
- xfree (result);
- result = xstrprintf ("<%s>", str);
- return result;
+ return string_printf ("<%s>", str);
}
static const char *
static char *decoding_buffer = NULL;
static size_t decoding_buffer_size = 0;
+ /* With function descriptors on PPC64, the value of a symbol named
+ ".FN", if it exists, is the entry point of the function "FN". */
+ if (encoded[0] == '.')
+ encoded += 1;
+
/* The name of the Ada main procedure starts with "_ada_".
This prefix is not part of the decoded name, so skip this part
if we see this prefix. */
bits = value_bitsize (component);
if (gdbarch_bits_big_endian (get_type_arch (value_type (container))))
- move_bits (value_contents_writeable (container) + offset_in_container,
- value_bitpos (container) + bit_offset_in_container,
- value_contents (val),
- TYPE_LENGTH (value_type (component)) * TARGET_CHAR_BIT - bits,
- bits, 1);
+ {
+ int src_offset;
+
+ if (is_scalar_type (check_typedef (value_type (component))))
+ src_offset
+ = 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);
+ }
else
move_bits (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. */
+
+bool
+ada_is_access_to_unconstrained_array (struct type *type)
+{
+ return (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
+ && is_thick_pntr (ada_typedef_target_type (type)));
+}
+
/* The value of the element of array ARR at the ARITY indices given in IND.
ARR may be either a simple array, GNAT array descriptor, or pointer
thereto. */
for (k = 0; k < arity; k += 1)
{
+ struct type *saved_elt_type = TYPE_TARGET_TYPE (elt_type);
+
if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY)
error (_("too many subscripts (%d expected)"), k);
+
elt = value_subscript (elt, pos_atr (ind[k]));
+
+ if (ada_is_access_to_unconstrained_array (saved_elt_type)
+ && TYPE_CODE (value_type (elt)) != TYPE_CODE_TYPEDEF)
+ {
+ /* The element is a typedef to an unconstrained array,
+ except that the value_subscript call stripped the
+ typedef layer. The typedef layer is GNAT's way to
+ specify that the element is, at the source level, an
+ access to the unconstrained array, rather than the
+ unconstrained array. So, we need to restore that
+ typedef layer, which we can do by forcing the element's
+ type back to its original type. Otherwise, the returned
+ value is going to be printed as the array, rather
+ than as an access. Another symptom of the same issue
+ would be that an expression trying to dereference the
+ element would also be improperly rejected. */
+ deprecated_set_value_type (elt, saved_elt_type);
+ }
+
+ elt_type = ada_check_typedef (value_type (elt));
}
+
return elt;
}
struct value **argvec; /* Vector of operand types (alloca'ed). */
int nargs; /* Number of operands. */
int oplen;
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
argvec = NULL;
nargs = 0;
case OP_VAR_VALUE:
if (SYMBOL_DOMAIN (exp->elts[pc + 2].symbol) == UNDEF_DOMAIN)
{
- struct block_symbol *candidates;
+ std::vector<struct block_symbol> candidates;
int n_candidates;
n_candidates =
(exp->elts[pc + 2].symbol),
exp->elts[pc + 1].block, VAR_DOMAIN,
&candidates);
- make_cleanup (xfree, candidates);
if (n_candidates > 1)
{
else if (n_candidates == 1)
i = 0;
else if (deprocedure_p
- && !is_nonfunction (candidates, n_candidates))
+ && !is_nonfunction (candidates.data (), n_candidates))
{
i = ada_resolve_function
- (candidates, n_candidates, NULL, 0,
+ (candidates.data (), n_candidates, NULL, 0,
SYMBOL_LINKAGE_NAME (exp->elts[pc + 2].symbol),
context_type);
if (i < 0)
{
printf_filtered (_("Multiple matches for %s\n"),
SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
- user_select_syms (candidates, n_candidates, 1);
+ user_select_syms (candidates.data (), n_candidates, 1);
i = 0;
}
&& (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol))
== TYPE_CODE_FUNC))
{
- replace_operator_with_call (expp, pc, 0, 0,
+ replace_operator_with_call (expp, pc, 0, 4,
exp->elts[pc + 2].symbol,
exp->elts[pc + 1].block);
exp = expp->get ();
if (exp->elts[pc + 3].opcode == OP_VAR_VALUE
&& SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN)
{
- struct block_symbol *candidates;
+ std::vector<struct block_symbol> candidates;
int n_candidates;
n_candidates =
(exp->elts[pc + 5].symbol),
exp->elts[pc + 4].block, VAR_DOMAIN,
&candidates);
- make_cleanup (xfree, candidates);
if (n_candidates == 1)
i = 0;
else
{
i = ada_resolve_function
- (candidates, n_candidates,
+ (candidates.data (), n_candidates,
argvec, nargs,
SYMBOL_LINKAGE_NAME (exp->elts[pc + 5].symbol),
context_type);
case UNOP_ABS:
if (possible_user_operator_p (op, argvec))
{
- struct block_symbol *candidates;
+ std::vector<struct block_symbol> candidates;
int n_candidates;
n_candidates =
ada_lookup_symbol_list (ada_decoded_op_name (op),
(struct block *) NULL, VAR_DOMAIN,
&candidates);
- make_cleanup (xfree, candidates);
- i = ada_resolve_function (candidates, n_candidates, argvec, nargs,
- ada_decoded_op_name (op), NULL);
+ i = ada_resolve_function (candidates.data (), n_candidates, argvec,
+ nargs, ada_decoded_op_name (op), NULL);
if (i < 0)
break;
case OP_TYPE:
case OP_REGISTER:
- do_cleanups (old_chain);
return NULL;
}
*pos = pc;
- do_cleanups (old_chain);
if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
return evaluate_var_msym_value (EVAL_AVOID_SIDE_EFFECTS,
exp->elts[pc + 1].objfile,
if (prompt == NULL)
prompt = "> ";
- args = command_line_input (prompt, 0, annotation_suffix);
+ args = command_line_input (prompt, annotation_suffix);
if (args == NULL)
error_no_arg (_("one or more choice numbers"));
|| TYPE_NFIELDS (type) != 1)
return ADA_NOT_RENAMING;
- name = type_name_no_tag (type);
+ name = TYPE_NAME (type);
if (name == NULL)
return ADA_NOT_RENAMING;
So, for practical purposes, we consider them as the same. */
static int
-symbols_are_identical_enums (struct block_symbol *syms, int nsyms)
+symbols_are_identical_enums (const std::vector<struct block_symbol> &syms)
{
int i;
(see ada_identical_enum_types_p). */
/* Quick check: All symbols should have an enum type. */
- for (i = 0; i < nsyms; i++)
+ for (i = 0; i < syms.size (); i++)
if (TYPE_CODE (SYMBOL_TYPE (syms[i].symbol)) != TYPE_CODE_ENUM)
return 0;
/* Quick check: They should all have the same value. */
- for (i = 1; i < nsyms; i++)
+ for (i = 1; i < syms.size (); i++)
if (SYMBOL_VALUE (syms[i].symbol) != SYMBOL_VALUE (syms[0].symbol))
return 0;
/* Quick check: They should all have the same number of enumerals. */
- for (i = 1; i < nsyms; i++)
+ for (i = 1; i < syms.size (); i++)
if (TYPE_NFIELDS (SYMBOL_TYPE (syms[i].symbol))
!= TYPE_NFIELDS (SYMBOL_TYPE (syms[0].symbol)))
return 0;
/* All the sanity checks passed, so we might have a set of
identical enumeration types. Perform a more complete
comparison of the type of each symbol. */
- for (i = 1; i < nsyms; i++)
+ for (i = 1; i < syms.size (); i++)
if (!ada_identical_enum_types_p (SYMBOL_TYPE (syms[i].symbol),
SYMBOL_TYPE (syms[0].symbol)))
return 0;
return 1;
}
-/* Remove any non-debugging symbols in SYMS[0 .. NSYMS-1] that definitely
+/* Remove any non-debugging symbols in SYMS that definitely
duplicate other symbols in the list (The only case I know of where
this happens is when object files containing stabs-in-ecoff are
linked with files containing ordinary ecoff debugging symbols (or no
Returns the number of items in the modified list. */
static int
-remove_extra_symbols (struct block_symbol *syms, int nsyms)
+remove_extra_symbols (std::vector<struct block_symbol> *syms)
{
int i, j;
/* We should never be called with less than 2 symbols, as there
cannot be any extra symbol in that case. But it's easy to
handle, since we have nothing to do in that case. */
- if (nsyms < 2)
- return nsyms;
+ if (syms->size () < 2)
+ return syms->size ();
i = 0;
- while (i < nsyms)
+ while (i < syms->size ())
{
int remove_p = 0;
/* If two symbols have the same name and one of them is a stub type,
the get rid of the stub. */
- if (TYPE_STUB (SYMBOL_TYPE (syms[i].symbol))
- && SYMBOL_LINKAGE_NAME (syms[i].symbol) != NULL)
+ if (TYPE_STUB (SYMBOL_TYPE ((*syms)[i].symbol))
+ && SYMBOL_LINKAGE_NAME ((*syms)[i].symbol) != NULL)
{
- for (j = 0; j < nsyms; j++)
+ for (j = 0; j < syms->size (); j++)
{
if (j != i
- && !TYPE_STUB (SYMBOL_TYPE (syms[j].symbol))
- && SYMBOL_LINKAGE_NAME (syms[j].symbol) != NULL
- && strcmp (SYMBOL_LINKAGE_NAME (syms[i].symbol),
- SYMBOL_LINKAGE_NAME (syms[j].symbol)) == 0)
+ && !TYPE_STUB (SYMBOL_TYPE ((*syms)[j].symbol))
+ && SYMBOL_LINKAGE_NAME ((*syms)[j].symbol) != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME ((*syms)[i].symbol),
+ SYMBOL_LINKAGE_NAME ((*syms)[j].symbol)) == 0)
remove_p = 1;
}
}
/* Two symbols with the same name, same class and same address
should be identical. */
- else if (SYMBOL_LINKAGE_NAME (syms[i].symbol) != NULL
- && SYMBOL_CLASS (syms[i].symbol) == LOC_STATIC
- && is_nondebugging_type (SYMBOL_TYPE (syms[i].symbol)))
+ else if (SYMBOL_LINKAGE_NAME ((*syms)[i].symbol) != NULL
+ && SYMBOL_CLASS ((*syms)[i].symbol) == LOC_STATIC
+ && is_nondebugging_type (SYMBOL_TYPE ((*syms)[i].symbol)))
{
- for (j = 0; j < nsyms; j += 1)
+ for (j = 0; j < syms->size (); j += 1)
{
if (i != j
- && SYMBOL_LINKAGE_NAME (syms[j].symbol) != NULL
- && strcmp (SYMBOL_LINKAGE_NAME (syms[i].symbol),
- SYMBOL_LINKAGE_NAME (syms[j].symbol)) == 0
- && SYMBOL_CLASS (syms[i].symbol)
- == SYMBOL_CLASS (syms[j].symbol)
- && SYMBOL_VALUE_ADDRESS (syms[i].symbol)
- == SYMBOL_VALUE_ADDRESS (syms[j].symbol))
+ && SYMBOL_LINKAGE_NAME ((*syms)[j].symbol) != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME ((*syms)[i].symbol),
+ SYMBOL_LINKAGE_NAME ((*syms)[j].symbol)) == 0
+ && SYMBOL_CLASS ((*syms)[i].symbol)
+ == SYMBOL_CLASS ((*syms)[j].symbol)
+ && SYMBOL_VALUE_ADDRESS ((*syms)[i].symbol)
+ == SYMBOL_VALUE_ADDRESS ((*syms)[j].symbol))
remove_p = 1;
}
}
if (remove_p)
- {
- for (j = i + 1; j < nsyms; j += 1)
- syms[j - 1] = syms[j];
- nsyms -= 1;
- }
+ syms->erase (syms->begin () + i);
i += 1;
}
to ask the user to disambiguate anyways. And if we have to
present a multiple-choice menu, it's less confusing if the list
isn't missing some choices that were identical and yet distinct. */
- if (symbols_are_identical_enums (syms, nsyms))
- nsyms = 1;
+ if (symbols_are_identical_enums (*syms))
+ syms->resize (1);
- return nsyms;
+ return syms->size ();
}
/* Given a type that corresponds to a renaming entity, use the type name
So, to extract the scope, we search for the "___XR" extension,
and then backtrack until we find the first "__". */
- const char *name = type_name_no_tag (renaming_type);
+ const char *name = TYPE_NAME (renaming_type);
const char *suffix = strstr (name, "___XR");
const char *last;
to NAME not existing in our list of symbols. There is only one
small complication with library-level functions (see below). */
- char *fun_name;
-
/* If it is a function that has not been defined at library level,
then we should be able to look it up in the symbols. */
if (standard_lookup (name, NULL, VAR_DOMAIN) != NULL)
if (strstr (name, "__") != NULL)
return 0;
- fun_name = xstrprintf ("_ada_%s", name);
+ std::string fun_name = string_printf ("_ada_%s", name);
- return (standard_lookup (fun_name, NULL, VAR_DOMAIN) == NULL);
+ return (standard_lookup (fun_name.c_str (), NULL, VAR_DOMAIN) == NULL);
}
/* Return nonzero if SYM corresponds to a renaming entity that is
the user will be unable to print such rename entities. */
static int
-remove_irrelevant_renamings (struct block_symbol *syms,
- int nsyms, const struct block *current_block)
+remove_irrelevant_renamings (std::vector<struct block_symbol> *syms,
+ const struct block *current_block)
{
struct symbol *current_function;
const char *current_function_name;
a simple variable foo in the same block, discard the latter.
First, zero out such symbols, then compress. */
is_new_style_renaming = 0;
- for (i = 0; i < nsyms; i += 1)
+ for (i = 0; i < syms->size (); i += 1)
{
- struct symbol *sym = syms[i].symbol;
- const struct block *block = syms[i].block;
+ struct symbol *sym = (*syms)[i].symbol;
+ const struct block *block = (*syms)[i].block;
const char *name;
const char *suffix;
int j;
is_new_style_renaming = 1;
- for (j = 0; j < nsyms; j += 1)
- if (i != j && syms[j].symbol != NULL
- && strncmp (name, SYMBOL_LINKAGE_NAME (syms[j].symbol),
+ for (j = 0; j < syms->size (); j += 1)
+ if (i != j && (*syms)[j].symbol != NULL
+ && strncmp (name, SYMBOL_LINKAGE_NAME ((*syms)[j].symbol),
name_len) == 0
- && block == syms[j].block)
- syms[j].symbol = NULL;
+ && block == (*syms)[j].block)
+ (*syms)[j].symbol = NULL;
}
}
if (is_new_style_renaming)
{
int j, k;
- for (j = k = 0; j < nsyms; j += 1)
- if (syms[j].symbol != NULL)
+ for (j = k = 0; j < syms->size (); j += 1)
+ if ((*syms)[j].symbol != NULL)
{
- syms[k] = syms[j];
+ (*syms)[k] = (*syms)[j];
k += 1;
}
return k;
Abort if unable to do so. */
if (current_block == NULL)
- return nsyms;
+ return syms->size ();
current_function = block_linkage_function (current_block);
if (current_function == NULL)
- return nsyms;
+ return syms->size ();
current_function_name = SYMBOL_LINKAGE_NAME (current_function);
if (current_function_name == NULL)
- return nsyms;
+ return syms->size ();
/* Check each of the symbols, and remove it from the list if it is
a type corresponding to a renaming that is out of the scope of
the current block. */
i = 0;
- while (i < nsyms)
+ while (i < syms->size ())
{
- if (ada_parse_renaming (syms[i].symbol, NULL, NULL, NULL)
+ if (ada_parse_renaming ((*syms)[i].symbol, NULL, NULL, NULL)
== ADA_OBJECT_RENAMING
- && old_renaming_is_invisible (syms[i].symbol, current_function_name))
- {
- int j;
-
- for (j = i + 1; j < nsyms; j += 1)
- syms[j - 1] = syms[j];
- nsyms -= 1;
- }
+ && old_renaming_is_invisible ((*syms)[i].symbol,
+ current_function_name))
+ syms->erase (syms->begin () + i);
else
i += 1;
}
- return nsyms;
+ return syms->size ();
}
/* Add to OBSTACKP all symbols from BLOCK (and its super-blocks)
/* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if FULL_SEARCH
is non-zero, enclosing scope and in global scopes, returning the number of
matches.
- Sets *RESULTS to point to a newly allocated vector of (SYM,BLOCK) tuples,
- indicating the symbols found and the blocks and symbol tables (if
- any) in which they were found. This vector should be freed when
- no longer useful.
+ Fills *RESULTS with (SYM,BLOCK) tuples, indicating the symbols
+ found and the blocks and symbol tables (if any) in which they were
+ found.
When full_search is non-zero, any non-function/non-enumeral
symbol match within the nest of blocks whose innermost member is BLOCK,
ada_lookup_symbol_list_worker (const lookup_name_info &lookup_name,
const struct block *block,
domain_enum domain,
- struct block_symbol **results,
+ std::vector<struct block_symbol> *results,
int full_search)
{
int syms_from_global_search;
int ndefns;
- int results_size;
auto_obstack obstack;
ada_add_all_symbols (&obstack, block, lookup_name,
ndefns = num_defns_collected (&obstack);
- results_size = obstack_object_size (&obstack);
- *results = (struct block_symbol *) malloc (results_size);
- memcpy (*results, defns_collected (&obstack, 1), results_size);
+ struct block_symbol *base = defns_collected (&obstack, 1);
+ for (int i = 0; i < ndefns; ++i)
+ results->push_back (base[i]);
- ndefns = remove_extra_symbols (*results, ndefns);
+ ndefns = remove_extra_symbols (results);
if (ndefns == 0 && full_search && syms_from_global_search)
cache_symbol (ada_lookup_name (lookup_name), domain, NULL, NULL);
cache_symbol (ada_lookup_name (lookup_name), domain,
(*results)[0].symbol, (*results)[0].block);
- ndefns = remove_irrelevant_renamings (*results, ndefns, block);
+ ndefns = remove_irrelevant_renamings (results, block);
return ndefns;
}
/* Find symbols in DOMAIN matching NAME, in BLOCK and enclosing scope and
- in global scopes, returning the number of matches, and setting *RESULTS
- to a newly-allocated vector of (SYM,BLOCK) tuples. This newly-allocated
- vector should be freed when no longer useful.
+ in global scopes, returning the number of matches, and filling *RESULTS
+ with (SYM,BLOCK) tuples.
See ada_lookup_symbol_list_worker for further details. */
int
ada_lookup_symbol_list (const char *name, const struct block *block,
- domain_enum domain, struct block_symbol **results)
+ domain_enum domain,
+ std::vector<struct block_symbol> *results)
{
symbol_name_match_type name_match_type = name_match_type_from_name (name);
lookup_name_info lookup_name (name, name_match_type);
gdb::function_view<symbol_found_callback_ftype> callback)
{
int ndefs, i;
- struct block_symbol *results;
- struct cleanup *old_chain;
+ std::vector<struct block_symbol> results;
ndefs = ada_lookup_symbol_list_worker (name, block, domain, &results, 0);
- old_chain = make_cleanup (xfree, results);
for (i = 0; i < ndefs; ++i)
{
- if (!callback (results[i].symbol))
+ if (!callback (&results[i]))
break;
}
-
- do_cleanups (old_chain);
}
/* The result is as for ada_lookup_symbol_list with FULL_SEARCH set
if (is_a_field_of_this != NULL)
*is_a_field_of_this = 0;
- struct block_symbol *candidates;
+ std::vector<struct block_symbol> candidates;
int n_candidates;
- struct cleanup *old_chain;
n_candidates = ada_lookup_symbol_list (name, block0, domain, &candidates);
- old_chain = make_cleanup (xfree, candidates);
if (n_candidates == 0)
- {
- do_cleanups (old_chain);
- return {};
- }
+ return {};
block_symbol info = candidates[0];
info.symbol = fixup_symbol_section (info.symbol, NULL);
-
- do_cleanups (old_chain);
-
return info;
}
{
struct type *t, *t1;
struct value *v;
+ int check_tag;
v = NULL;
t1 = t = ada_check_typedef (value_type (arg));
if (!find_struct_field (name, t1, 0,
&field_type, &byte_offset, &bit_offset,
&bit_size, NULL))
- t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
- address, NULL, 1);
+ check_tag = 1;
+ else
+ check_tag = 0;
}
else
- t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
- address, NULL, 1);
+ check_tag = 0;
+
+ /* Convert to fixed type in all cases, so that we have proper
+ offsets to each field in unconstrained record types. */
+ t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
+ address, NULL, check_tag);
if (find_struct_field (name, t1, 0,
&field_type, &byte_offset, &bit_offset,
return 1;
else
{
- const char *type0_name = type_name_no_tag (type0);
- const char *type1_name = type_name_no_tag (type1);
+ const char *type0_name = TYPE_NAME (type0);
+ const char *type1_name = TYPE_NAME (type1);
if (type0_name != NULL && strstr (type0_name, "___XR") != NULL
&& (type1_name == NULL || strstr (type1_name, "___XR") == NULL))
return 0;
}
-/* The name of TYPE, which is either its TYPE_NAME, or, if that is
- null, its TYPE_TAG_NAME. Null if TYPE is null. */
+/* The name of TYPE, which is its TYPE_NAME. Null if TYPE is
+ null. */
const char *
ada_type_name (struct type *type)
{
if (type == NULL)
return NULL;
- else if (TYPE_NAME (type) != NULL)
- return TYPE_NAME (type);
- else
- return TYPE_TAG_NAME (type);
+ return TYPE_NAME (type);
}
/* Search the list of "descriptive" types associated to TYPE for a type
TYPE_FIELDS (type) = NULL;
INIT_CPLUS_SPECIFIC (type);
TYPE_NAME (type) = "<empty>";
- TYPE_TAG_NAME (type) = NULL;
TYPE_LENGTH (type) = 0;
return type;
}
TYPE_ALLOC (rtype, nfields * sizeof (struct field));
memset (TYPE_FIELDS (rtype), 0, sizeof (struct field) * nfields);
TYPE_NAME (rtype) = ada_type_name (type);
- TYPE_TAG_NAME (rtype) = NULL;
TYPE_FIXED_INSTANCE (rtype) = 1;
off = 0;
memcpy (TYPE_FIELDS (type), TYPE_FIELDS (type0),
sizeof (struct field) * nfields);
TYPE_NAME (type) = ada_type_name (type0);
- TYPE_TAG_NAME (type) = NULL;
TYPE_FIXED_INSTANCE (type) = 1;
TYPE_LENGTH (type) = 0;
}
memcpy (TYPE_FIELDS (rtype), TYPE_FIELDS (type),
sizeof (struct field) * nfields);
TYPE_NAME (rtype) = ada_type_name (type);
- TYPE_TAG_NAME (rtype) = NULL;
TYPE_FIXED_INSTANCE (rtype) = 1;
TYPE_LENGTH (rtype) = TYPE_LENGTH (type);
if (type == NULL)
return NULL;
- /* If our type is a typedef type of a fat pointer, then we're done.
+ /* If our type is an access to an unconstrained array, which is encoded
+ as a TYPE_CODE_TYPEDEF of a fat pointer, then we're done.
We don't want to strip the TYPE_CODE_TYPDEF layer, because this is
what allows us to distinguish between fat pointers that represent
array types, and fat pointers that represent array access types
(in both cases, the compiler implements them as fat pointers). */
- if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
- && is_thick_pntr (ada_typedef_target_type (type)))
+ if (ada_is_access_to_unconstrained_array (type))
return type;
type = check_typedef (type);
if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
|| !TYPE_STUB (type)
- || TYPE_TAG_NAME (type) == NULL)
+ || TYPE_NAME (type) == NULL)
return type;
else
{
- const char *name = TYPE_TAG_NAME (type);
+ const char *name = TYPE_NAME (type);
struct type *type1 = ada_find_any_type (name);
if (type1 == NULL)
ada_to_fixed_value (struct value *val)
{
val = unwrap_value (val);
- val = ada_to_fixed_value_create (value_type (val),
- value_address (val),
- val);
+ val = ada_to_fixed_value_create (value_type (val), value_address (val), val);
return val;
}
\f
return arg2;
if (ada_is_fixed_point_type (type))
- return (cast_to_fixed (type, arg2));
+ return cast_to_fixed (type, arg2);
if (ada_is_fixed_point_type (value_type (arg2)))
return cast_from_fixed (type, arg2);
{
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
- struct block_symbol *syms;
+ std::vector<struct block_symbol> syms;
int nsyms = ada_lookup_symbol_list_worker (lookup_name,
get_selected_block (0),
VAR_DOMAIN, &syms, 1);
- struct cleanup *old_chain = make_cleanup (xfree, syms);
if (nsyms != 1)
{
- do_cleanups (old_chain);
if (err_msg == NULL)
return 0;
else
error (("%s"), err_msg);
}
- struct value *result = value_of_variable (syms[0].symbol, syms[0].block);
- do_cleanups (old_chain);
- return result;
+ return value_of_variable (syms[0].symbol, syms[0].block);
}
/* Value of integer variable named NAME in the current environment.
loaded. If it is not started, this may mean that the symbol is
in a shared library. */
- if (ptid_get_pid (inferior_ptid) == 0)
+ if (inferior_ptid.pid () == 0)
error (_("Unable to insert catchpoint. Try to start the program first."));
/* At this point, we know that we are debugging an Ada program and
if (strcmp (func_name.get (),
data->exception_info->catch_exception_sym) == 0)
break; /* We found the frame we were looking for... */
- fi = get_prev_frame (fi);
}
+ fi = get_prev_frame (fi);
}
if (fi == NULL)
struct ada_catchpoint : public breakpoint
{
- ~ada_catchpoint () override;
-
/* The name of the specific exception the user specified. */
- char *excep_string;
+ std::string excep_string;
};
/* Parse the exception condition string in the context of each of the
struct bp_location *bl;
/* Nothing to do if there's no specific exception to catch. */
- if (c->excep_string == NULL)
+ if (c->excep_string.empty ())
return;
/* Same if there are no locations... */
/* Compute the condition expression in text form, from the specific
expection we want to catch. */
std::string cond_string
- = ada_exception_catchpoint_cond_string (c->excep_string, ex);
+ = ada_exception_catchpoint_cond_string (c->excep_string.c_str (), ex);
/* Iterate over all the catchpoint's locations, and parse an
expression for each. */
}
}
-/* ada_catchpoint destructor. */
-
-ada_catchpoint::~ada_catchpoint ()
-{
- xfree (this->excep_string);
-}
-
/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
structure for all exception catchpoint kinds. */
int stop;
/* With no specific exception, should always stop. */
- if (c->excep_string == NULL)
+ if (c->excep_string.empty ())
return 1;
if (ada_loc->excep_cond_expr == NULL)
switch (ex)
{
case ada_catch_exception:
- if (c->excep_string != NULL)
+ if (!c->excep_string.empty ())
{
- char *msg = xstrprintf (_("`%s' Ada exception"), c->excep_string);
+ std::string msg = string_printf (_("`%s' Ada exception"),
+ c->excep_string.c_str ());
uiout->field_string ("what", msg);
- xfree (msg);
}
else
uiout->field_string ("what", "all Ada exceptions");
break;
case ada_catch_handlers:
- if (c->excep_string != NULL)
+ if (!c->excep_string.empty ())
{
uiout->field_fmt ("what",
_("`%s' Ada exception handlers"),
- c->excep_string);
+ c->excep_string.c_str ());
}
else
uiout->field_string ("what", "all Ada exceptions handlers");
switch (ex)
{
case ada_catch_exception:
- if (c->excep_string != NULL)
+ if (!c->excep_string.empty ())
{
std::string info = string_printf (_("`%s' Ada exception"),
- c->excep_string);
+ c->excep_string.c_str ());
uiout->text (info.c_str ());
}
else
break;
case ada_catch_handlers:
- if (c->excep_string != NULL)
+ if (!c->excep_string.empty ())
{
std::string info
= string_printf (_("`%s' Ada exception handlers"),
- c->excep_string);
+ c->excep_string.c_str ());
uiout->text (info.c_str ());
}
else
{
case ada_catch_exception:
fprintf_filtered (fp, "catch exception");
- if (c->excep_string != NULL)
- fprintf_filtered (fp, " %s", c->excep_string);
+ if (!c->excep_string.empty ())
+ fprintf_filtered (fp, " %s", c->excep_string.c_str ());
break;
case ada_catch_exception_unhandled:
static struct breakpoint_ops catch_handlers_breakpoint_ops;
-/* Return a newly allocated copy of the first space-separated token
- in ARGSP, and then adjust ARGSP to point immediately after that
- token.
-
- Return NULL if ARGPS does not contain any more tokens. */
-
-static char *
-ada_get_next_arg (const char **argsp)
-{
- const char *args = *argsp;
- const char *end;
- char *result;
-
- args = skip_spaces (args);
- if (args[0] == '\0')
- return NULL; /* No more arguments. */
-
- /* Find the end of the current argument. */
-
- end = skip_to_space (args);
-
- /* Adjust ARGSP to point to the start of the next argument. */
-
- *argsp = end;
-
- /* Make a copy of the current argument and return it. */
-
- result = (char *) xmalloc (end - args + 1);
- strncpy (result, args, end - args);
- result[end - args] = '\0';
-
- return result;
-}
-
/* Split the arguments specified in a "catch exception" command.
Set EX to the appropriate catchpoint type.
Set EXCEP_STRING to the name of the specific exception if
catch_ada_exception_command_split (const char *args,
bool is_catch_handlers_cmd,
enum ada_exception_catchpoint_kind *ex,
- char **excep_string,
- std::string &cond_string)
+ std::string *excep_string,
+ std::string *cond_string)
{
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
- char *exception_name;
- char *cond = NULL;
+ std::string exception_name;
- exception_name = ada_get_next_arg (&args);
- if (exception_name != NULL && strcmp (exception_name, "if") == 0)
+ exception_name = extract_arg (&args);
+ if (exception_name == "if")
{
/* This is not an exception name; this is the start of a condition
expression for a catchpoint on all exceptions. So, "un-get"
this token, and set exception_name to NULL. */
- xfree (exception_name);
- exception_name = NULL;
+ exception_name.clear ();
args -= 2;
}
- make_cleanup (xfree, exception_name);
/* Check to see if we have a condition. */
if (args[0] == '\0')
error (_("Condition missing after `if' keyword"));
- cond = xstrdup (args);
- make_cleanup (xfree, cond);
+ *cond_string = args;
args += strlen (args);
}
if (args[0] != '\0')
error (_("Junk at end of expression"));
- discard_cleanups (old_chain);
-
if (is_catch_handlers_cmd)
{
/* Catch handling of exceptions. */
*ex = ada_catch_handlers;
*excep_string = exception_name;
}
- else if (exception_name == NULL)
+ else if (exception_name.empty ())
{
/* Catch all exceptions. */
*ex = ada_catch_exception;
- *excep_string = NULL;
+ excep_string->clear ();
}
- else if (strcmp (exception_name, "unhandled") == 0)
+ else if (exception_name == "unhandled")
{
/* Catch unhandled exceptions. */
*ex = ada_catch_exception_unhandled;
- *excep_string = NULL;
+ excep_string->clear ();
}
else
{
*ex = ada_catch_exception;
*excep_string = exception_name;
}
- if (cond != NULL)
- cond_string.assign (cond);
}
/* Return the name of the symbol on which we should break in order to
/* Return the symtab_and_line that should be used to insert an exception
catchpoint of the TYPE kind.
- EXCEP_STRING should contain the name of a specific exception that
- the catchpoint should catch, or NULL otherwise.
-
ADDR_STRING returns the name of the function where the real
breakpoint that implements the catchpoints is set, depending on the
type of catchpoint we need to create. */
static struct symtab_and_line
-ada_exception_sal (enum ada_exception_catchpoint_kind ex, char *excep_string,
+ada_exception_sal (enum ada_exception_catchpoint_kind ex,
const char **addr_string, const struct breakpoint_ops **ops)
{
const char *sym_name;
sym_name = ada_exception_sym_name (ex);
sym = standard_lookup (sym_name, NULL, VAR_DOMAIN);
- /* We can assume that SYM is not NULL at this stage. If the symbol
- did not exist, ada_exception_support_info_sniffer would have
- raised an exception.
+ if (sym == NULL)
+ error (_("Catchpoint symbol not found: %s"), sym_name);
- Also, ada_exception_support_info_sniffer should have already
- verified that SYM is a function symbol. */
- gdb_assert (sym != NULL);
- gdb_assert (SYMBOL_CLASS (sym) == LOC_BLOCK);
+ if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+ error (_("Unable to insert catchpoint. %s is not a function."), sym_name);
/* Set ADDR_STRING. */
*addr_string = xstrdup (sym_name);
EX_KIND is the kind of exception catchpoint to be created.
- If EXCEPT_STRING is NULL, this catchpoint is expected to trigger
+ If EXCEPT_STRING is empty, this catchpoint is expected to trigger
for all exceptions. Otherwise, EXCEPT_STRING indicates the name
- of the exception to which this catchpoint applies. When not NULL,
- the string must be allocated on the heap, and its deallocation
- is no longer the responsibility of the caller.
+ of the exception to which this catchpoint applies.
- COND_STRING, if not NULL, is the catchpoint condition. This string
- must be allocated on the heap, and its deallocation is no longer
- the responsibility of the caller.
+ COND_STRING, if not empty, is the catchpoint condition.
TEMPFLAG, if nonzero, means that the underlying breakpoint
should be temporary.
void
create_ada_exception_catchpoint (struct gdbarch *gdbarch,
enum ada_exception_catchpoint_kind ex_kind,
- char *excep_string,
+ const std::string &excep_string,
const std::string &cond_string,
int tempflag,
int disabled,
{
const char *addr_string = NULL;
const struct breakpoint_ops *ops = NULL;
- struct symtab_and_line sal
- = ada_exception_sal (ex_kind, excep_string, &addr_string, &ops);
+ 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,
struct gdbarch *gdbarch = get_current_arch ();
int tempflag;
enum ada_exception_catchpoint_kind ex_kind;
- char *excep_string = NULL;
+ std::string excep_string;
std::string cond_string;
tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
if (!arg)
arg = "";
catch_ada_exception_command_split (arg, false, &ex_kind, &excep_string,
- cond_string);
+ &cond_string);
create_ada_exception_catchpoint (gdbarch, ex_kind,
excep_string, cond_string,
tempflag, 1 /* enabled */,
struct gdbarch *gdbarch = get_current_arch ();
int tempflag;
enum ada_exception_catchpoint_kind ex_kind;
- char *excep_string = NULL;
+ std::string excep_string;
std::string cond_string;
tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
if (!arg)
arg = "";
catch_ada_exception_command_split (arg, true, &ex_kind, &excep_string,
- cond_string);
+ &cond_string);
create_ada_exception_catchpoint (gdbarch, ex_kind,
excep_string, cond_string,
tempflag, 1 /* enabled */,
arg = "";
catch_ada_assert_command_split (arg, cond_string);
create_ada_exception_catchpoint (gdbarch, ada_catch_assert,
- NULL, cond_string,
+ "", cond_string,
tempflag, 1 /* enabled */,
from_tty);
}
static int
ada_is_exception_sym (struct symbol *sym)
{
- const char *type_name = type_name_no_tag (SYMBOL_TYPE (sym));
+ const char *type_name = TYPE_NAME (SYMBOL_TYPE (sym));
return (SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_BLOCK
ada_extensions,
&ada_exp_descriptor,
parse,
- ada_yyerror,
resolve,
ada_printchar, /* Print a character constant */
ada_printstr, /* Function to print string constant */