| Index: gdb/ada-lang.c
|
| diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
|
| index 2d8169478903aa89c423ce6fa9bda67ee0af6143..aa090af81bd7f04fde80c2c3fbd385830986b513 100644
|
| --- a/gdb/ada-lang.c
|
| +++ b/gdb/ada-lang.c
|
| @@ -57,12 +57,14 @@
|
| #include "observer.h"
|
| #include "vec.h"
|
| #include "stack.h"
|
| +#include "gdb_vecs.h"
|
|
|
| #include "psymtab.h"
|
| #include "value.h"
|
| #include "mi/mi-common.h"
|
| #include "arch-utils.h"
|
| #include "exceptions.h"
|
| +#include "cli/cli-utils.h"
|
|
|
| /* Define whether or not the C operator '/' truncates towards zero for
|
| differently signed operands (truncation direction is undefined in C).
|
| @@ -221,7 +223,7 @@ static struct value *ada_search_struct_field (char *, struct value *, int,
|
| static struct value *ada_value_primitive_field (struct value *, int, int,
|
| struct type *);
|
|
|
| -static int find_struct_field (char *, struct type *, int,
|
| +static int find_struct_field (const char *, struct type *, int,
|
| struct type **, int *, int *, int *, int *);
|
|
|
| static struct value *ada_to_fixed_value_create (struct type *, CORE_ADDR,
|
| @@ -269,6 +271,8 @@ static struct value *ada_evaluate_subexp (struct type *, struct expression *,
|
|
|
| static void ada_forward_operator_length (struct expression *, int, int *,
|
| int *);
|
| +
|
| +static struct type *ada_find_any_type (const char *name);
|
|
|
|
|
|
|
| @@ -686,7 +690,7 @@ ada_discrete_type_high_bound (struct type *type)
|
| case TYPE_CODE_RANGE:
|
| return TYPE_HIGH_BOUND (type);
|
| case TYPE_CODE_ENUM:
|
| - return TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
|
| + return TYPE_FIELD_ENUMVAL (type, TYPE_NFIELDS (type) - 1);
|
| case TYPE_CODE_BOOL:
|
| return 1;
|
| case TYPE_CODE_CHAR:
|
| @@ -697,7 +701,7 @@ ada_discrete_type_high_bound (struct type *type)
|
| }
|
| }
|
|
|
| -/* The largest value in the domain of TYPE, a discrete type, as an integer. */
|
| +/* The smallest value in the domain of TYPE, a discrete type, as an integer. */
|
| LONGEST
|
| ada_discrete_type_low_bound (struct type *type)
|
| {
|
| @@ -706,7 +710,7 @@ ada_discrete_type_low_bound (struct type *type)
|
| case TYPE_CODE_RANGE:
|
| return TYPE_LOW_BOUND (type);
|
| case TYPE_CODE_ENUM:
|
| - return TYPE_FIELD_BITPOS (type, 0);
|
| + return TYPE_FIELD_ENUMVAL (type, 0);
|
| case TYPE_CODE_BOOL:
|
| return 0;
|
| case TYPE_CODE_CHAR:
|
| @@ -731,6 +735,46 @@ get_base_type (struct type *type)
|
| }
|
| return type;
|
| }
|
| +
|
| +/* Return a decoded version of the given VALUE. This means returning
|
| + a value whose type is obtained by applying all the GNAT-specific
|
| + encondings, making the resulting type a static but standard description
|
| + of the initial type. */
|
| +
|
| +struct value *
|
| +ada_get_decoded_value (struct value *value)
|
| +{
|
| + struct type *type = ada_check_typedef (value_type (value));
|
| +
|
| + if (ada_is_array_descriptor_type (type)
|
| + || (ada_is_constrained_packed_array_type (type)
|
| + && TYPE_CODE (type) != TYPE_CODE_PTR))
|
| + {
|
| + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) /* array access type. */
|
| + value = ada_coerce_to_simple_array_ptr (value);
|
| + else
|
| + value = ada_coerce_to_simple_array (value);
|
| + }
|
| + else
|
| + value = ada_to_fixed_value (value);
|
| +
|
| + return value;
|
| +}
|
| +
|
| +/* Same as ada_get_decoded_value, but with the given TYPE.
|
| + Because there is no associated actual value for this type,
|
| + the resulting type might be a best-effort approximation in
|
| + the case of dynamic types. */
|
| +
|
| +struct type *
|
| +ada_get_decoded_type (struct type *type)
|
| +{
|
| + type = to_static_fixed_type (type);
|
| + if (ada_is_constrained_packed_array_type (type))
|
| + type = ada_coerce_to_simple_array_type (type);
|
| + return type;
|
| +}
|
| +
|
|
|
|
|
| /* Language Selection */
|
| @@ -1368,7 +1412,7 @@ ada_fixup_array_indexes_type (struct type *index_desc_type)
|
| /* Fixup each field of INDEX_DESC_TYPE. */
|
| for (i = 0; i < TYPE_NFIELDS (index_desc_type); i++)
|
| {
|
| - char *name = TYPE_FIELD_NAME (index_desc_type, i);
|
| + const char *name = TYPE_FIELD_NAME (index_desc_type, i);
|
| struct type *raw_type = ada_check_typedef (ada_find_any_type (name));
|
|
|
| if (raw_type)
|
| @@ -1960,8 +2004,8 @@ ada_is_unconstrained_packed_array_type (struct type *type)
|
| static long
|
| decode_packed_array_bitsize (struct type *type)
|
| {
|
| - char *raw_name;
|
| - char *tail;
|
| + const char *raw_name;
|
| + const char *tail;
|
| long bits;
|
|
|
| /* Access to arrays implemented as fat pointers are encoded as a typedef
|
| @@ -2004,22 +2048,30 @@ constrained_packed_array_type (struct type *type, long *elt_bits)
|
| {
|
| struct type *new_elt_type;
|
| struct type *new_type;
|
| + struct type *index_type_desc;
|
| + struct type *index_type;
|
| LONGEST low_bound, high_bound;
|
|
|
| type = ada_check_typedef (type);
|
| if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
|
| return type;
|
|
|
| + index_type_desc = ada_find_parallel_type (type, "___XA");
|
| + if (index_type_desc)
|
| + index_type = to_fixed_range_type (TYPE_FIELD_TYPE (index_type_desc, 0),
|
| + NULL);
|
| + else
|
| + index_type = TYPE_INDEX_TYPE (type);
|
| +
|
| new_type = alloc_type_copy (type);
|
| new_elt_type =
|
| constrained_packed_array_type (ada_check_typedef (TYPE_TARGET_TYPE (type)),
|
| elt_bits);
|
| - create_array_type (new_type, new_elt_type, TYPE_INDEX_TYPE (type));
|
| + create_array_type (new_type, new_elt_type, index_type);
|
| TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits;
|
| TYPE_NAME (new_type) = ada_type_name (type);
|
|
|
| - if (get_discrete_bounds (TYPE_INDEX_TYPE (type),
|
| - &low_bound, &high_bound) < 0)
|
| + if (get_discrete_bounds (index_type, &low_bound, &high_bound) < 0)
|
| low_bound = high_bound = 0;
|
| if (high_bound < low_bound)
|
| *elt_bits = TYPE_LENGTH (new_type) = 0;
|
| @@ -2040,9 +2092,9 @@ constrained_packed_array_type (struct type *type, long *elt_bits)
|
| static struct type *
|
| decode_constrained_packed_array_type (struct type *type)
|
| {
|
| - char *raw_name = ada_type_name (ada_check_typedef (type));
|
| + const char *raw_name = ada_type_name (ada_check_typedef (type));
|
| char *name;
|
| - char *tail;
|
| + const char *tail;
|
| struct type *shadow_type;
|
| long bits;
|
|
|
| @@ -2245,10 +2297,9 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
|
| }
|
| else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
|
| {
|
| - v = value_at (type,
|
| - value_address (obj) + offset);
|
| + v = value_at (type, value_address (obj));
|
| bytes = (unsigned char *) alloca (len);
|
| - read_memory (value_address (v), bytes, len);
|
| + read_memory (value_address (v) + offset, bytes, len);
|
| }
|
| else
|
| {
|
| @@ -2258,18 +2309,22 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
|
|
|
| if (obj != NULL)
|
| {
|
| - CORE_ADDR new_addr;
|
| + long new_offset = offset;
|
|
|
| set_value_component_location (v, obj);
|
| - new_addr = value_address (obj) + offset;
|
| set_value_bitpos (v, bit_offset + value_bitpos (obj));
|
| set_value_bitsize (v, bit_size);
|
| if (value_bitpos (v) >= HOST_CHAR_BIT)
|
| {
|
| - ++new_addr;
|
| + ++new_offset;
|
| set_value_bitpos (v, value_bitpos (v) - HOST_CHAR_BIT);
|
| }
|
| - set_value_address (v, new_addr);
|
| + 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);
|
| + value_incref (obj);
|
| }
|
| else
|
| set_value_bitsize (v, bit_size);
|
| @@ -2479,8 +2534,7 @@ ada_value_assign (struct value *toval, struct value *fromval)
|
| else
|
| move_bits (buffer, value_bitpos (toval),
|
| value_contents (fromval), 0, bits, 0);
|
| - write_memory (to_addr, buffer, len);
|
| - observer_notify_memory_changed (to_addr, len, buffer);
|
| + write_memory_with_notification (to_addr, buffer, len);
|
|
|
| val = value_copy (toval);
|
| memcpy (value_contents_raw (val), value_contents (fromval),
|
| @@ -3055,7 +3109,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
|
| ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
|
| (exp->elts[pc + 2].symbol),
|
| exp->elts[pc + 1].block, VAR_DOMAIN,
|
| - &candidates);
|
| + &candidates, 1);
|
|
|
| if (n_candidates > 1)
|
| {
|
| @@ -3147,7 +3201,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
|
| ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
|
| (exp->elts[pc + 5].symbol),
|
| exp->elts[pc + 4].block, VAR_DOMAIN,
|
| - &candidates);
|
| + &candidates, 1);
|
| if (n_candidates == 1)
|
| i = 0;
|
| else
|
| @@ -3199,7 +3253,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
|
| n_candidates =
|
| ada_lookup_symbol_list (ada_encode (ada_decoded_op_name (op)),
|
| (struct block *) NULL, VAR_DOMAIN,
|
| - &candidates);
|
| + &candidates, 1);
|
| i = ada_resolve_function (candidates, n_candidates, argvec, nargs,
|
| ada_decoded_op_name (op), NULL);
|
| if (i < 0)
|
| @@ -3405,7 +3459,7 @@ ada_resolve_function (struct ada_symbol_info syms[],
|
| such symbols by their trailing number (__N or $N). */
|
|
|
| static int
|
| -encoded_ordered_before (char *N0, char *N1)
|
| +encoded_ordered_before (const char *N0, const char *N1)
|
| {
|
| if (N1 == NULL)
|
| return 0;
|
| @@ -3611,8 +3665,7 @@ get_selections (int *choices, int n_choices, int max_results,
|
| char *args2;
|
| int choice, j;
|
|
|
| - while (isspace (*args))
|
| - args += 1;
|
| + args = skip_spaces (args);
|
| if (*args == '\0' && n_chosen == 0)
|
| error_no_arg (_("one or more choice numbers"));
|
| else if (*args == '\0')
|
| @@ -3990,8 +4043,30 @@ parse_old_style_renaming (struct type *type,
|
| if (len != NULL)
|
| *len = suffix - info;
|
| return kind;
|
| -}
|
| +}
|
| +
|
| +/* Compute the value of the given RENAMING_SYM, which is expected to
|
| + be a symbol encoding a renaming expression. BLOCK is the block
|
| + used to evaluate the renaming. */
|
| +
|
| +static struct value *
|
| +ada_read_renaming_var_value (struct symbol *renaming_sym,
|
| + struct block *block)
|
| +{
|
| + char *sym_name;
|
| + struct expression *expr;
|
| + struct value *value;
|
| + struct cleanup *old_chain = NULL;
|
|
|
| + sym_name = xstrdup (SYMBOL_LINKAGE_NAME (renaming_sym));
|
| + old_chain = make_cleanup (xfree, sym_name);
|
| + expr = parse_exp_1 (&sym_name, 0, block, 0);
|
| + make_cleanup (free_current_contents, &expr);
|
| + value = evaluate_expression (expr);
|
| +
|
| + do_cleanups (old_chain);
|
| + return value;
|
| +}
|
|
|
|
|
| /* Evaluation: Function Calls */
|
| @@ -4063,7 +4138,7 @@ ada_convert_actual (struct value *actual, struct type *formal_type0)
|
| }
|
| else
|
| return actual;
|
| - return value_cast_pointers (formal_type, result);
|
| + return value_cast_pointers (formal_type, result, 0);
|
| }
|
| else if (TYPE_CODE (actual_type) == TYPE_CODE_PTR)
|
| return ada_value_ind (actual);
|
| @@ -4161,6 +4236,18 @@ cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
|
|
|
| /* Symbol Lookup */
|
|
|
| +/* Return nonzero if wild matching should be used when searching for
|
| + all symbols matching LOOKUP_NAME.
|
| +
|
| + LOOKUP_NAME is expected to be a symbol name after transformation
|
| + for Ada lookups (see ada_name_for_lookup). */
|
| +
|
| +static int
|
| +should_use_wild_match (const char *lookup_name)
|
| +{
|
| + return (strstr (lookup_name, "__") == NULL);
|
| +}
|
| +
|
| /* Return the result of a standard (literal, C-like) lookup of NAME in
|
| given DOMAIN, visible from lexical block BLOCK. */
|
|
|
| @@ -4168,7 +4255,8 @@ static struct symbol *
|
| standard_lookup (const char *name, const struct block *block,
|
| domain_enum domain)
|
| {
|
| - struct symbol *sym;
|
| + /* Initialize it just to avoid a GCC false warning. */
|
| + struct symbol *sym = NULL;
|
|
|
| if (lookup_cached_symbol (name, domain, &sym, NULL))
|
| return sym;
|
| @@ -4235,8 +4323,8 @@ lesseq_defined_than (struct symbol *sym0, struct symbol *sym1)
|
| {
|
| struct type *type0 = SYMBOL_TYPE (sym0);
|
| struct type *type1 = SYMBOL_TYPE (sym1);
|
| - char *name0 = SYMBOL_LINKAGE_NAME (sym0);
|
| - char *name1 = SYMBOL_LINKAGE_NAME (sym1);
|
| + const char *name0 = SYMBOL_LINKAGE_NAME (sym0);
|
| + const char *name1 = SYMBOL_LINKAGE_NAME (sym1);
|
| int len0 = strlen (name0);
|
|
|
| return
|
| @@ -4317,8 +4405,8 @@ defns_collected (struct obstack *obstackp, int finish)
|
| }
|
|
|
| /* Return a minimal symbol matching NAME according to Ada decoding
|
| - rules. Returns NULL if there is no such minimal symbol. Names
|
| - prefixed with "standard__" are handled specially: "standard__" is
|
| + rules. Returns NULL if there is no such minimal symbol. Names
|
| + prefixed with "standard__" are handled specially: "standard__" is
|
| first stripped off, and only static and global symbols are searched. */
|
|
|
| struct minimal_symbol *
|
| @@ -4326,19 +4414,21 @@ ada_lookup_simple_minsym (const char *name)
|
| {
|
| struct objfile *objfile;
|
| struct minimal_symbol *msymbol;
|
| - int wild_match;
|
| + const int wild_match_p = should_use_wild_match (name);
|
|
|
| + /* Special case: If the user specifies a symbol name inside package
|
| + Standard, do a non-wild matching of the symbol name without
|
| + the "standard__" prefix. This was primarily introduced in order
|
| + to allow the user to specifically access the standard exceptions
|
| + using, for instance, Standard.Constraint_Error when Constraint_Error
|
| + is ambiguous (due to the user defining its own Constraint_Error
|
| + entity inside its program). */
|
| if (strncmp (name, "standard__", sizeof ("standard__") - 1) == 0)
|
| - {
|
| - name += sizeof ("standard__") - 1;
|
| - wild_match = 0;
|
| - }
|
| - else
|
| - wild_match = (strstr (name, "__") == NULL);
|
| + name += sizeof ("standard__") - 1;
|
|
|
| ALL_MSYMBOLS (objfile, msymbol)
|
| {
|
| - if (match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
|
| + if (match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match_p)
|
| && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
|
| return msymbol;
|
| }
|
| @@ -4349,13 +4439,13 @@ ada_lookup_simple_minsym (const char *name)
|
| /* For all subprograms that statically enclose the subprogram of the
|
| selected frame, add symbols matching identifier NAME in DOMAIN
|
| and their blocks to the list of data in OBSTACKP, as for
|
| - ada_add_block_symbols (q.v.). If WILD, treat as NAME with a
|
| - wildcard prefix. */
|
| + ada_add_block_symbols (q.v.). If WILD_MATCH_P, treat as NAME
|
| + with a wildcard prefix. */
|
|
|
| static void
|
| add_symbols_from_enclosing_procs (struct obstack *obstackp,
|
| const char *name, domain_enum namespace,
|
| - int wild_match)
|
| + int wild_match_p)
|
| {
|
| }
|
|
|
| @@ -4365,7 +4455,7 @@ add_symbols_from_enclosing_procs (struct obstack *obstackp,
|
| static int
|
| is_nondebugging_type (struct type *type)
|
| {
|
| - char *name = ada_type_name (type);
|
| + const char *name = ada_type_name (type);
|
|
|
| return (name != NULL && strcmp (name, "<variable, no debug info>") == 0);
|
| }
|
| @@ -4389,15 +4479,15 @@ ada_identical_enum_types_p (struct type *type1, struct type *type2)
|
|
|
| /* All enums in the type should have an identical underlying value. */
|
| for (i = 0; i < TYPE_NFIELDS (type1); i++)
|
| - if (TYPE_FIELD_BITPOS (type1, i) != TYPE_FIELD_BITPOS (type2, i))
|
| + if (TYPE_FIELD_ENUMVAL (type1, i) != TYPE_FIELD_ENUMVAL (type2, i))
|
| return 0;
|
|
|
| /* All enumerals should also have the same name (modulo any numerical
|
| suffix). */
|
| for (i = 0; i < TYPE_NFIELDS (type1); i++)
|
| {
|
| - char *name_1 = TYPE_FIELD_NAME (type1, i);
|
| - char *name_2 = TYPE_FIELD_NAME (type2, i);
|
| + const char *name_1 = TYPE_FIELD_NAME (type1, i);
|
| + const char *name_2 = TYPE_FIELD_NAME (type2, i);
|
| int len_1 = strlen (name_1);
|
| int len_2 = strlen (name_2);
|
|
|
| @@ -4632,7 +4722,7 @@ is_package_name (const char *name)
|
| not visible from FUNCTION_NAME. */
|
|
|
| static int
|
| -old_renaming_is_invisible (const struct symbol *sym, char *function_name)
|
| +old_renaming_is_invisible (const struct symbol *sym, const char *function_name)
|
| {
|
| char *scope;
|
|
|
| @@ -4702,7 +4792,7 @@ remove_irrelevant_renamings (struct ada_symbol_info *syms,
|
| int nsyms, const struct block *current_block)
|
| {
|
| struct symbol *current_function;
|
| - char *current_function_name;
|
| + const char *current_function_name;
|
| int i;
|
| int is_new_style_renaming;
|
|
|
| @@ -4792,20 +4882,23 @@ remove_irrelevant_renamings (struct ada_symbol_info *syms,
|
| If no match was found, then extend the search to "enclosing"
|
| routines (in other words, if we're inside a nested function,
|
| search the symbols defined inside the enclosing functions).
|
| + If WILD_MATCH_P is nonzero, perform the naming matching in
|
| + "wild" mode (see function "wild_match" for more info).
|
|
|
| Note: This function assumes that OBSTACKP has 0 (zero) element in it. */
|
|
|
| static void
|
| ada_add_local_symbols (struct obstack *obstackp, const char *name,
|
| struct block *block, domain_enum domain,
|
| - int wild_match)
|
| + int wild_match_p)
|
| {
|
| int block_depth = 0;
|
|
|
| while (block != NULL)
|
| {
|
| block_depth += 1;
|
| - ada_add_block_symbols (obstackp, block, name, domain, NULL, wild_match);
|
| + ada_add_block_symbols (obstackp, block, name, domain, NULL,
|
| + wild_match_p);
|
|
|
| /* If we found a non-function match, assume that's the one. */
|
| if (is_nonfunction (defns_collected (obstackp, 0),
|
| @@ -4818,7 +4911,7 @@ ada_add_local_symbols (struct obstack *obstackp, const char *name,
|
| /* If no luck so far, try to find NAME as a local symbol in some lexically
|
| enclosing subprogram. */
|
| if (num_defns_collected (obstackp) == 0 && block_depth > 2)
|
| - add_symbols_from_enclosing_procs (obstackp, name, domain, wild_match);
|
| + add_symbols_from_enclosing_procs (obstackp, name, domain, wild_match_p);
|
| }
|
|
|
| /* An object of this type is used as the user_data argument when
|
| @@ -4922,8 +5015,8 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
|
| struct objfile *objfile;
|
| struct match_data data;
|
|
|
| + memset (&data, 0, sizeof data);
|
| data.obstackp = obstackp;
|
| - data.arg_sym = NULL;
|
|
|
| ALL_OBJFILES (objfile)
|
| {
|
| @@ -4957,28 +5050,30 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
|
| }
|
|
|
| /* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing
|
| - scope and in global scopes, returning the number of matches. Sets
|
| - *RESULTS to point to a vector of (SYM,BLOCK) tuples,
|
| + scope and in global scopes, returning the number of matches.
|
| + Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples,
|
| indicating the symbols found and the blocks and symbol tables (if
|
| - any) in which they were found. This vector are transient---good only to
|
| - the next call of ada_lookup_symbol_list. Any non-function/non-enumeral
|
| + any) in which they were found. This vector are transient---good only to
|
| + the next call of ada_lookup_symbol_list. Any non-function/non-enumeral
|
| symbol match within the nest of blocks whose innermost member is BLOCK0,
|
| is the one match returned (no other matches in that or
|
| - enclosing blocks is returned). If there are any matches in or
|
| - surrounding BLOCK0, then these alone are returned. Otherwise, the
|
| - search extends to global and file-scope (static) symbol tables.
|
| - Names prefixed with "standard__" are handled specially: "standard__"
|
| + enclosing blocks is returned). If there are any matches in or
|
| + surrounding BLOCK0, then these alone are returned. Otherwise, if
|
| + FULL_SEARCH is non-zero, then the search extends to global and
|
| + file-scope (static) symbol tables.
|
| + Names prefixed with "standard__" are handled specially: "standard__"
|
| is first stripped off, and only static and global symbols are searched. */
|
|
|
| int
|
| ada_lookup_symbol_list (const char *name0, const struct block *block0,
|
| - domain_enum namespace,
|
| - struct ada_symbol_info **results)
|
| + domain_enum namespace,
|
| + struct ada_symbol_info **results,
|
| + int full_search)
|
| {
|
| struct symbol *sym;
|
| struct block *block;
|
| const char *name;
|
| - int wild_match;
|
| + const int wild_match_p = should_use_wild_match (name0);
|
| int cacheIfUnique;
|
| int ndefns;
|
|
|
| @@ -4989,7 +5084,6 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
|
|
|
| /* Search specified block and its superiors. */
|
|
|
| - wild_match = (strstr (name0, "__") == NULL);
|
| name = name0;
|
| block = (struct block *) block0; /* FIXME: No cast ought to be
|
| needed, but adding const will
|
| @@ -5004,7 +5098,6 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
|
| entity inside its program). */
|
| if (strncmp (name0, "standard__", sizeof ("standard__") - 1) == 0)
|
| {
|
| - wild_match = 0;
|
| block = NULL;
|
| name = name0 + sizeof ("standard__") - 1;
|
| }
|
| @@ -5012,8 +5105,8 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
|
| /* Check the non-global symbols. If we have ANY match, then we're done. */
|
|
|
| ada_add_local_symbols (&symbol_list_obstack, name, block, namespace,
|
| - wild_match);
|
| - if (num_defns_collected (&symbol_list_obstack) > 0)
|
| + wild_match_p);
|
| + if (num_defns_collected (&symbol_list_obstack) > 0 || !full_search)
|
| goto done;
|
|
|
| /* No non-global symbols found. Check our cache to see if we have
|
| @@ -5031,14 +5124,14 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
|
| /* Search symbols from all global blocks. */
|
|
|
| add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 1,
|
| - wild_match);
|
| + wild_match_p);
|
|
|
| /* Now add symbols from all per-file blocks if we've gotten no hits
|
| (not strictly correct, but perhaps better than an error). */
|
|
|
| if (num_defns_collected (&symbol_list_obstack) == 0)
|
| add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 0,
|
| - wild_match);
|
| + wild_match_p);
|
|
|
| done:
|
| ndefns = num_defns_collected (&symbol_list_obstack);
|
| @@ -5046,10 +5139,10 @@ done:
|
|
|
| ndefns = remove_extra_symbols (*results, ndefns);
|
|
|
| - if (ndefns == 0)
|
| + if (ndefns == 0 && full_search)
|
| cache_symbol (name0, namespace, NULL, NULL);
|
|
|
| - if (ndefns == 1 && cacheIfUnique)
|
| + if (ndefns == 1 && full_search && cacheIfUnique)
|
| cache_symbol (name0, namespace, (*results)[0].sym, (*results)[0].block);
|
|
|
| ndefns = remove_irrelevant_renamings (*results, ndefns, block0);
|
| @@ -5087,13 +5180,13 @@ ada_name_for_lookup (const char *name)
|
| static void
|
| ada_iterate_over_symbols (const struct block *block,
|
| const char *name, domain_enum domain,
|
| - int (*callback) (struct symbol *, void *),
|
| + symbol_found_callback_ftype *callback,
|
| void *data)
|
| {
|
| int ndefs, i;
|
| struct ada_symbol_info *results;
|
|
|
| - ndefs = ada_lookup_symbol_list (name, block, domain, &results);
|
| + ndefs = ada_lookup_symbol_list (name, block, domain, &results, 0);
|
| for (i = 0; i < ndefs; ++i)
|
| {
|
| if (! (*callback) (results[i].sym, data))
|
| @@ -5101,41 +5194,52 @@ ada_iterate_over_symbols (const struct block *block,
|
| }
|
| }
|
|
|
| -struct symbol *
|
| -ada_lookup_encoded_symbol (const char *name, const struct block *block0,
|
| - domain_enum namespace, struct block **block_found)
|
| +/* The result is as for ada_lookup_symbol_list with FULL_SEARCH set
|
| + to 1, but choosing the first symbol found if there are multiple
|
| + choices.
|
| +
|
| + The result is stored in *INFO, which must be non-NULL.
|
| + If no match is found, INFO->SYM is set to NULL. */
|
| +
|
| +void
|
| +ada_lookup_encoded_symbol (const char *name, const struct block *block,
|
| + domain_enum namespace,
|
| + struct ada_symbol_info *info)
|
| {
|
| struct ada_symbol_info *candidates;
|
| int n_candidates;
|
|
|
| - n_candidates = ada_lookup_symbol_list (name, block0, namespace, &candidates);
|
| + gdb_assert (info != NULL);
|
| + memset (info, 0, sizeof (struct ada_symbol_info));
|
|
|
| - if (n_candidates == 0)
|
| - return NULL;
|
| + n_candidates = ada_lookup_symbol_list (name, block, namespace, &candidates,
|
| + 1);
|
|
|
| - if (block_found != NULL)
|
| - *block_found = candidates[0].block;
|
| + if (n_candidates == 0)
|
| + return;
|
|
|
| - return fixup_symbol_section (candidates[0].sym, NULL);
|
| -}
|
| + *info = candidates[0];
|
| + info->sym = fixup_symbol_section (info->sym, NULL);
|
| +}
|
|
|
| /* Return a symbol in DOMAIN matching NAME, in BLOCK0 and enclosing
|
| scope and in global scopes, or NULL if none. NAME is folded and
|
| encoded first. Otherwise, the result is as for ada_lookup_symbol_list,
|
| choosing the first symbol if there are multiple choices.
|
| - *IS_A_FIELD_OF_THIS is set to 0 and *SYMTAB is set to the symbol
|
| - table in which the symbol was found (in both cases, these
|
| - assignments occur only if the pointers are non-null). */
|
| + If IS_A_FIELD_OF_THIS is not NULL, it is set to zero. */
|
| +
|
| struct symbol *
|
| ada_lookup_symbol (const char *name, const struct block *block0,
|
| domain_enum namespace, int *is_a_field_of_this)
|
| {
|
| + struct ada_symbol_info info;
|
| +
|
| if (is_a_field_of_this != NULL)
|
| *is_a_field_of_this = 0;
|
|
|
| - return
|
| - ada_lookup_encoded_symbol (ada_encode (ada_fold_name (name)),
|
| - block0, namespace, NULL);
|
| + ada_lookup_encoded_symbol (ada_encode (ada_fold_name (name)),
|
| + block0, namespace, &info);
|
| + return info.sym;
|
| }
|
|
|
| static struct symbol *
|
| @@ -5154,6 +5258,7 @@ ada_lookup_symbol_nonlocal (const char *name,
|
|
|
| [.$][0-9]+ [nested subprogram suffix, on platforms such as GNU/Linux]
|
| ___[0-9]+ [nested subprogram suffix, on platforms such as HP/UX]
|
| + TKB [subprogram suffix for task bodies]
|
| _E[0-9]+[bs]$ [protected object entry suffixes]
|
| (X[nb]*)?((\$|__)[0-9](_?[0-9]+)|___(JM|LJM|X([FDBUP].*|R[^T]?)))?$
|
|
|
| @@ -5199,6 +5304,11 @@ is_name_suffix (const char *str)
|
| return 1;
|
| }
|
|
|
| + /* "TKB" suffixes are used for subprograms implementing task bodies. */
|
| +
|
| + if (strcmp (str, "TKB") == 0)
|
| + return 1;
|
| +
|
| #if 0
|
| /* FIXME: brobecker/2005-09-23: Protected Object subprograms end
|
| with a N at the end. Unfortunately, the compiler uses the same
|
| @@ -5360,7 +5470,7 @@ advance_wild_match (const char **namep, const char *name0, int target0)
|
| static int
|
| wild_match (const char *name, const char *patn)
|
| {
|
| - const char *p, *n;
|
| + const char *p;
|
| const char *name0 = name;
|
|
|
| while (1)
|
| @@ -5405,7 +5515,7 @@ ada_add_block_symbols (struct obstack *obstackp,
|
| domain_enum domain, struct objfile *objfile,
|
| int wild)
|
| {
|
| - struct dict_iterator iter;
|
| + struct block_iterator iter;
|
| int name_len = strlen (name);
|
| /* A matching argument symbol, if any. */
|
| struct symbol *arg_sym;
|
| @@ -5417,9 +5527,8 @@ ada_add_block_symbols (struct obstack *obstackp,
|
| found_sym = 0;
|
| if (wild)
|
| {
|
| - for (sym = dict_iter_match_first (BLOCK_DICT (block), name,
|
| - wild_match, &iter);
|
| - sym != NULL; sym = dict_iter_match_next (name, wild_match, &iter))
|
| + for (sym = block_iter_match_first (block, name, wild_match, &iter);
|
| + sym != NULL; sym = block_iter_match_next (name, wild_match, &iter))
|
| {
|
| if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
| SYMBOL_DOMAIN (sym), domain)
|
| @@ -5441,9 +5550,8 @@ ada_add_block_symbols (struct obstack *obstackp,
|
| }
|
| else
|
| {
|
| - for (sym = dict_iter_match_first (BLOCK_DICT (block), name,
|
| - full_match, &iter);
|
| - sym != NULL; sym = dict_iter_match_next (name, full_match, &iter))
|
| + for (sym = block_iter_match_first (block, name, full_match, &iter);
|
| + sym != NULL; sym = block_iter_match_next (name, full_match, &iter))
|
| {
|
| if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
| SYMBOL_DOMAIN (sym), domain))
|
| @@ -5530,14 +5638,14 @@ ada_add_block_symbols (struct obstack *obstackp,
|
| does not need to be deallocated, but is only good until the next call.
|
|
|
| TEXT_LEN is equal to the length of TEXT.
|
| - Perform a wild match if WILD_MATCH is set.
|
| - ENCODED should be set if TEXT represents the start of a symbol name
|
| + Perform a wild match if WILD_MATCH_P is set.
|
| + ENCODED_P should be set if TEXT represents the start of a symbol name
|
| in its encoded form. */
|
|
|
| static const char *
|
| symbol_completion_match (const char *sym_name,
|
| const char *text, int text_len,
|
| - int wild_match, int encoded)
|
| + int wild_match_p, int encoded_p)
|
| {
|
| const int verbatim_match = (text[0] == '<');
|
| int match = 0;
|
| @@ -5554,7 +5662,7 @@ symbol_completion_match (const char *sym_name,
|
| if (strncmp (sym_name, text, text_len) == 0)
|
| match = 1;
|
|
|
| - if (match && !encoded)
|
| + if (match && !encoded_p)
|
| {
|
| /* One needed check before declaring a positive match is to verify
|
| that iff we are doing a verbatim match, the decoded version
|
| @@ -5585,7 +5693,7 @@ symbol_completion_match (const char *sym_name,
|
|
|
| /* Second: Try wild matching... */
|
|
|
| - if (!match && wild_match)
|
| + if (!match && wild_match_p)
|
| {
|
| /* Since we are doing wild matching, this means that TEXT
|
| may represent an unqualified symbol name. We therefore must
|
| @@ -5604,14 +5712,12 @@ symbol_completion_match (const char *sym_name,
|
| if (verbatim_match)
|
| sym_name = add_angle_brackets (sym_name);
|
|
|
| - if (!encoded)
|
| + if (!encoded_p)
|
| sym_name = ada_decode (sym_name);
|
|
|
| return sym_name;
|
| }
|
|
|
| -DEF_VEC_P (char_ptr);
|
| -
|
| /* A companion function to ada_make_symbol_completion_list().
|
| Check if SYM_NAME represents a symbol which name would be suitable
|
| to complete TEXT (TEXT_LEN is the length of TEXT), in which case
|
| @@ -5622,8 +5728,8 @@ DEF_VEC_P (char_ptr);
|
| completion should be performed. These two parameters are used to
|
| determine which part of the symbol name should be added to the
|
| completion vector.
|
| - if WILD_MATCH is set, then wild matching is performed.
|
| - ENCODED should be set if TEXT represents a symbol name in its
|
| + if WILD_MATCH_P is set, then wild matching is performed.
|
| + ENCODED_P should be set if TEXT represents a symbol name in its
|
| encoded formed (in which case the completion should also be
|
| encoded). */
|
|
|
| @@ -5632,10 +5738,10 @@ symbol_completion_add (VEC(char_ptr) **sv,
|
| const char *sym_name,
|
| const char *text, int text_len,
|
| const char *orig_text, const char *word,
|
| - int wild_match, int encoded)
|
| + int wild_match_p, int encoded_p)
|
| {
|
| const char *match = symbol_completion_match (sym_name, text, text_len,
|
| - wild_match, encoded);
|
| + wild_match_p, encoded_p);
|
| char *completion;
|
|
|
| if (match == NULL)
|
| @@ -5682,8 +5788,7 @@ struct add_partial_datum
|
|
|
| /* A callback for expand_partial_symbol_names. */
|
| static int
|
| -ada_expand_partial_symbol_name (const struct language_defn *language,
|
| - const char *name, void *user_data)
|
| +ada_expand_partial_symbol_name (const char *name, void *user_data)
|
| {
|
| struct add_partial_datum *data = user_data;
|
|
|
| @@ -5691,17 +5796,16 @@ ada_expand_partial_symbol_name (const struct language_defn *language,
|
| data->wild_match, data->encoded) != NULL;
|
| }
|
|
|
| -/* Return a list of possible symbol names completing TEXT0. The list
|
| - is NULL terminated. WORD is the entire command on which completion
|
| - is made. */
|
| +/* Return a list of possible symbol names completing TEXT0. WORD is
|
| + the entire command on which completion is made. */
|
|
|
| -static char **
|
| +static VEC (char_ptr) *
|
| ada_make_symbol_completion_list (char *text0, char *word)
|
| {
|
| char *text;
|
| int text_len;
|
| - int wild_match;
|
| - int encoded;
|
| + int wild_match_p;
|
| + int encoded_p;
|
| VEC(char_ptr) *completions = VEC_alloc (char_ptr, 128);
|
| struct symbol *sym;
|
| struct symtab *s;
|
| @@ -5709,15 +5813,15 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| struct objfile *objfile;
|
| struct block *b, *surrounding_static_block = 0;
|
| int i;
|
| - struct dict_iterator iter;
|
| + struct block_iterator iter;
|
|
|
| if (text0[0] == '<')
|
| {
|
| text = xstrdup (text0);
|
| make_cleanup (xfree, text);
|
| text_len = strlen (text);
|
| - wild_match = 0;
|
| - encoded = 1;
|
| + wild_match_p = 0;
|
| + encoded_p = 1;
|
| }
|
| else
|
| {
|
| @@ -5727,12 +5831,12 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| for (i = 0; i < text_len; i++)
|
| text[i] = tolower (text[i]);
|
|
|
| - encoded = (strstr (text0, "__") != NULL);
|
| + encoded_p = (strstr (text0, "__") != NULL);
|
| /* If the name contains a ".", then the user is entering a fully
|
| qualified entity name, and the match must not be done in wild
|
| mode. Similarly, if the user wants to complete what looks like
|
| an encoded name, the match must not be done in wild mode. */
|
| - wild_match = (strchr (text0, '.') == NULL && !encoded);
|
| + wild_match_p = (strchr (text0, '.') == NULL && !encoded_p);
|
| }
|
|
|
| /* First, look at the partial symtab symbols. */
|
| @@ -5744,8 +5848,8 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| data.text_len = text_len;
|
| data.text0 = text0;
|
| data.word = word;
|
| - data.wild_match = wild_match;
|
| - data.encoded = encoded;
|
| + data.wild_match = wild_match_p;
|
| + data.encoded = encoded_p;
|
| expand_partial_symbol_names (ada_expand_partial_symbol_name, &data);
|
| }
|
|
|
| @@ -5758,7 +5862,8 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| {
|
| QUIT;
|
| symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (msymbol),
|
| - text, text_len, text0, word, wild_match, encoded);
|
| + text, text_len, text0, word, wild_match_p,
|
| + encoded_p);
|
| }
|
|
|
| /* Search upwards from currently selected frame (so that we can
|
| @@ -5773,7 +5878,7 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| {
|
| symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym),
|
| text, text_len, text0, word,
|
| - wild_match, encoded);
|
| + wild_match_p, encoded_p);
|
| }
|
| }
|
|
|
| @@ -5788,7 +5893,7 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| {
|
| symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym),
|
| text, text_len, text0, word,
|
| - wild_match, encoded);
|
| + wild_match_p, encoded_p);
|
| }
|
| }
|
|
|
| @@ -5803,28 +5908,11 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| {
|
| symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym),
|
| text, text_len, text0, word,
|
| - wild_match, encoded);
|
| + wild_match_p, encoded_p);
|
| }
|
| }
|
|
|
| - /* Append the closing NULL entry. */
|
| - VEC_safe_push (char_ptr, completions, NULL);
|
| -
|
| - /* Make a copy of the COMPLETIONS VEC before we free it, and then
|
| - return the copy. It's unfortunate that we have to make a copy
|
| - of an array that we're about to destroy, but there is nothing much
|
| - we can do about it. Fortunately, it's typically not a very large
|
| - array. */
|
| - {
|
| - const size_t completions_size =
|
| - VEC_length (char_ptr, completions) * sizeof (char *);
|
| - char **result = xmalloc (completions_size);
|
| -
|
| - memcpy (result, VEC_address (char_ptr, completions), completions_size);
|
| -
|
| - VEC_free (char_ptr, completions);
|
| - return result;
|
| - }
|
| + return completions;
|
| }
|
|
|
| /* Field Access */
|
| @@ -5835,7 +5923,7 @@ ada_make_symbol_completion_list (char *text0, char *word)
|
| static int
|
| ada_is_dispatch_table_ptr_type (struct type *type)
|
| {
|
| - char *name;
|
| + const char *name;
|
|
|
| if (TYPE_CODE (type) != TYPE_CODE_PTR)
|
| return 0;
|
| @@ -5855,7 +5943,7 @@ ada_is_ignored_field (struct type *type, int field_num)
|
| {
|
| if (field_num < 0 || field_num > TYPE_NFIELDS (type))
|
| return 1;
|
| -
|
| +
|
| /* Check the name of that field. */
|
| {
|
| const char *name = TYPE_FIELD_NAME (type, field_num);
|
| @@ -5866,8 +5954,13 @@ ada_is_ignored_field (struct type *type, int field_num)
|
| if (name == NULL)
|
| return 1;
|
|
|
| - /* A field named "_parent" is internally generated by GNAT for
|
| - tagged types, and should not be printed either. */
|
| + /* Normally, fields whose name start with an underscore ("_")
|
| + are fields that have been internally generated by the compiler,
|
| + and thus should not be printed. The "_parent" field is special,
|
| + however: This is a field internally generated by the compiler
|
| + for tagged types, and it contains the components inherited from
|
| + the parent type. This field should not be printed as is, but
|
| + should not be ignored either. */
|
| if (name[0] == '_' && strncmp (name, "_parent", 7) != 0)
|
| return 1;
|
| }
|
| @@ -5957,105 +6050,110 @@ type_from_tag (struct value *tag)
|
| return NULL;
|
| }
|
|
|
| -struct tag_args
|
| +/* Return the "ada__tags__type_specific_data" type. */
|
| +
|
| +static struct type *
|
| +ada_get_tsd_type (struct inferior *inf)
|
| {
|
| - struct value *tag;
|
| - char *name;
|
| -};
|
| + struct ada_inferior_data *data = get_ada_inferior_data (inf);
|
|
|
| + if (data->tsd_type == 0)
|
| + data->tsd_type = ada_find_any_type ("ada__tags__type_specific_data");
|
| + return data->tsd_type;
|
| +}
|
|
|
| -static int ada_tag_name_1 (void *);
|
| -static int ada_tag_name_2 (struct tag_args *);
|
| +/* Return the TSD (type-specific data) associated to the given TAG.
|
| + TAG is assumed to be the tag of a tagged-type entity.
|
|
|
| -/* Wrapper function used by ada_tag_name. Given a struct tag_args*
|
| - value ARGS, sets ARGS->name to the tag name of ARGS->tag.
|
| - The value stored in ARGS->name is valid until the next call to
|
| - ada_tag_name_1. */
|
| + May return NULL if we are unable to get the TSD. */
|
|
|
| -static int
|
| -ada_tag_name_1 (void *args0)
|
| +static struct value *
|
| +ada_get_tsd_from_tag (struct value *tag)
|
| {
|
| - struct tag_args *args = (struct tag_args *) args0;
|
| - static char name[1024];
|
| - char *p;
|
| struct value *val;
|
| + struct type *type;
|
|
|
| - args->name = NULL;
|
| - val = ada_value_struct_elt (args->tag, "tsd", 1);
|
| - if (val == NULL)
|
| - return ada_tag_name_2 (args);
|
| - val = ada_value_struct_elt (val, "expanded_name", 1);
|
| - if (val == NULL)
|
| - return 0;
|
| - read_memory_string (value_as_address (val), name, sizeof (name) - 1);
|
| - for (p = name; *p != '\0'; p += 1)
|
| - if (isalpha (*p))
|
| - *p = tolower (*p);
|
| - args->name = name;
|
| - return 0;
|
| -}
|
| + /* First option: The TSD is simply stored as a field of our TAG.
|
| + Only older versions of GNAT would use this format, but we have
|
| + to test it first, because there are no visible markers for
|
| + the current approach except the absence of that field. */
|
|
|
| -/* Return the "ada__tags__type_specific_data" type. */
|
| + val = ada_value_struct_elt (tag, "tsd", 1);
|
| + if (val)
|
| + return val;
|
|
|
| -static struct type *
|
| -ada_get_tsd_type (struct inferior *inf)
|
| -{
|
| - struct ada_inferior_data *data = get_ada_inferior_data (inf);
|
| + /* Try the second representation for the dispatch table (in which
|
| + there is no explicit 'tsd' field in the referent of the tag pointer,
|
| + and instead the tsd pointer is stored just before the dispatch
|
| + table. */
|
|
|
| - if (data->tsd_type == 0)
|
| - data->tsd_type = ada_find_any_type ("ada__tags__type_specific_data");
|
| - return data->tsd_type;
|
| + type = ada_get_tsd_type (current_inferior());
|
| + if (type == NULL)
|
| + return NULL;
|
| + type = lookup_pointer_type (lookup_pointer_type (type));
|
| + val = value_cast (type, tag);
|
| + if (val == NULL)
|
| + return NULL;
|
| + return value_ind (value_ptradd (val, -1));
|
| }
|
|
|
| -/* Utility function for ada_tag_name_1 that tries the second
|
| - representation for the dispatch table (in which there is no
|
| - explicit 'tsd' field in the referent of the tag pointer, and instead
|
| - the tsd pointer is stored just before the dispatch table. */
|
| -
|
| -static int
|
| -ada_tag_name_2 (struct tag_args *args)
|
| +/* Given the TSD of a tag (type-specific data), return a string
|
| + containing the name of the associated type.
|
| +
|
| + The returned value is good until the next call. May return NULL
|
| + if we are unable to determine the tag name. */
|
| +
|
| +static char *
|
| +ada_tag_name_from_tsd (struct value *tsd)
|
| {
|
| - struct type *info_type;
|
| static char name[1024];
|
| char *p;
|
| - struct value *val, *valp;
|
| + struct value *val;
|
|
|
| - args->name = NULL;
|
| - info_type = ada_get_tsd_type (current_inferior());
|
| - if (info_type == NULL)
|
| - return 0;
|
| - info_type = lookup_pointer_type (lookup_pointer_type (info_type));
|
| - valp = value_cast (info_type, args->tag);
|
| - if (valp == NULL)
|
| - return 0;
|
| - val = value_ind (value_ptradd (valp, -1));
|
| - if (val == NULL)
|
| - return 0;
|
| - val = ada_value_struct_elt (val, "expanded_name", 1);
|
| + val = ada_value_struct_elt (tsd, "expanded_name", 1);
|
| if (val == NULL)
|
| - return 0;
|
| + return NULL;
|
| read_memory_string (value_as_address (val), name, sizeof (name) - 1);
|
| for (p = name; *p != '\0'; p += 1)
|
| if (isalpha (*p))
|
| *p = tolower (*p);
|
| - args->name = name;
|
| - return 0;
|
| + return name;
|
| }
|
|
|
| /* The type name of the dynamic type denoted by the 'tag value TAG, as
|
| - a C string. */
|
| + a C string.
|
| +
|
| + Return NULL if the TAG is not an Ada tag, or if we were unable to
|
| + determine the name of that tag. The result is good until the next
|
| + call. */
|
|
|
| const char *
|
| ada_tag_name (struct value *tag)
|
| {
|
| - struct tag_args args;
|
| + volatile struct gdb_exception e;
|
| + char *name = NULL;
|
|
|
| if (!ada_is_tag_type (value_type (tag)))
|
| return NULL;
|
| - args.tag = tag;
|
| - args.name = NULL;
|
| - catch_errors (ada_tag_name_1, &args, NULL, RETURN_MASK_ALL);
|
| - return args.name;
|
| +
|
| + /* It is perfectly possible that an exception be raised while trying
|
| + to determine the TAG's name, even under normal circumstances:
|
| + The associated variable may be uninitialized or corrupted, for
|
| + instance. We do not let any exception propagate past this point.
|
| + instead we return NULL.
|
| +
|
| + We also do not print the error message either (which often is very
|
| + low-level (Eg: "Cannot read memory at 0x[...]"), but instead let
|
| + the caller print a more meaningful message if necessary. */
|
| + TRY_CATCH (e, RETURN_MASK_ERROR)
|
| + {
|
| + struct value *tsd = ada_get_tsd_from_tag (tag);
|
| +
|
| + if (tsd != NULL)
|
| + name = ada_tag_name_from_tsd (tsd);
|
| + }
|
| +
|
| + return name;
|
| }
|
|
|
| /* The parent type of TYPE, or NULL if none. */
|
| @@ -6348,7 +6446,7 @@ ada_value_primitive_field (struct value *arg1, int offset, int fieldno,
|
| Returns 1 if found, 0 otherwise. */
|
|
|
| static int
|
| -find_struct_field (char *name, struct type *type, int offset,
|
| +find_struct_field (const char *name, struct type *type, int offset,
|
| struct type **field_type_p,
|
| int *byte_offset_p, int *bit_offset_p, int *bit_size_p,
|
| int *index_p)
|
| @@ -6370,7 +6468,7 @@ find_struct_field (char *name, struct type *type, int offset,
|
| {
|
| int bit_pos = TYPE_FIELD_BITPOS (type, i);
|
| int fld_offset = offset + bit_pos / 8;
|
| - char *t_field_name = TYPE_FIELD_NAME (type, i);
|
| + const char *t_field_name = TYPE_FIELD_NAME (type, i);
|
|
|
| if (t_field_name == NULL)
|
| continue;
|
| @@ -6447,7 +6545,7 @@ ada_search_struct_field (char *name, struct value *arg, int offset,
|
| type = ada_check_typedef (type);
|
| for (i = 0; i < TYPE_NFIELDS (type); i += 1)
|
| {
|
| - char *t_field_name = TYPE_FIELD_NAME (type, i);
|
| + const char *t_field_name = TYPE_FIELD_NAME (type, i);
|
|
|
| if (t_field_name == NULL)
|
| continue;
|
| @@ -6706,7 +6804,7 @@ ada_lookup_struct_elt_type (struct type *type, char *name, int refok,
|
|
|
| for (i = 0; i < TYPE_NFIELDS (type); i += 1)
|
| {
|
| - char *t_field_name = TYPE_FIELD_NAME (type, i);
|
| + const char *t_field_name = TYPE_FIELD_NAME (type, i);
|
| struct type *t;
|
| int disp;
|
|
|
| @@ -6745,7 +6843,7 @@ ada_lookup_struct_elt_type (struct type *type, char *name, int refok,
|
| NOT wrapped in a struct, since the compiler sometimes
|
| generates these for unchecked variant types. Revisit
|
| if the compiler changes this practice. */
|
| - char *v_field_name = TYPE_FIELD_NAME (field_type, j);
|
| + const char *v_field_name = TYPE_FIELD_NAME (field_type, j);
|
| disp = 0;
|
| if (v_field_name != NULL
|
| && field_name_match (v_field_name, name))
|
| @@ -6883,7 +6981,7 @@ ada_which_variant_applies (struct type *var_type, struct type *outer_type,
|
| struct value *
|
| ada_value_ind (struct value *val0)
|
| {
|
| - struct value *val = unwrap_value (value_ind (val0));
|
| + struct value *val = value_ind (val0);
|
|
|
| return ada_to_fixed_value (val);
|
| }
|
| @@ -6899,7 +6997,6 @@ ada_coerce_ref (struct value *val0)
|
| struct value *val = val0;
|
|
|
| val = coerce_ref (val);
|
| - val = unwrap_value (val);
|
| return ada_to_fixed_value (val);
|
| }
|
| else
|
| @@ -6946,10 +7043,10 @@ field_alignment (struct type *type, int f)
|
| return atoi (name + align_offset) * TARGET_CHAR_BIT;
|
| }
|
|
|
| -/* Find a symbol named NAME. Ignores ambiguity. */
|
| +/* Find a typedef or tag symbol named NAME. Ignores ambiguity. */
|
|
|
| -struct symbol *
|
| -ada_find_any_symbol (const char *name)
|
| +static struct symbol *
|
| +ada_find_any_type_symbol (const char *name)
|
| {
|
| struct symbol *sym;
|
|
|
| @@ -6965,10 +7062,10 @@ ada_find_any_symbol (const char *name)
|
| solely for types defined by debug info, it will not search the GDB
|
| primitive types. */
|
|
|
| -struct type *
|
| +static struct type *
|
| ada_find_any_type (const char *name)
|
| {
|
| - struct symbol *sym = ada_find_any_symbol (name);
|
| + struct symbol *sym = ada_find_any_type_symbol (name);
|
|
|
| if (sym != NULL)
|
| return SYMBOL_TYPE (sym);
|
| @@ -6976,23 +7073,28 @@ ada_find_any_type (const char *name)
|
| return NULL;
|
| }
|
|
|
| -/* Given NAME and an associated BLOCK, search all symbols for
|
| - NAME suffixed with "___XR", which is the ``renaming'' symbol
|
| - associated to NAME. Return this symbol if found, return
|
| - NULL otherwise. */
|
| +/* Given NAME_SYM and an associated BLOCK, find a "renaming" symbol
|
| + associated with NAME_SYM's name. NAME_SYM may itself be a renaming
|
| + symbol, in which case it is returned. Otherwise, this looks for
|
| + symbols whose name is that of NAME_SYM suffixed with "___XR".
|
| + Return symbol if found, and NULL otherwise. */
|
|
|
| struct symbol *
|
| -ada_find_renaming_symbol (const char *name, struct block *block)
|
| +ada_find_renaming_symbol (struct symbol *name_sym, struct block *block)
|
| {
|
| + const char *name = SYMBOL_LINKAGE_NAME (name_sym);
|
| struct symbol *sym;
|
|
|
| + if (strstr (name, "___XR") != NULL)
|
| + return name_sym;
|
| +
|
| sym = find_old_style_renaming_symbol (name, block);
|
|
|
| if (sym != NULL)
|
| return sym;
|
|
|
| /* Not right yet. FIXME pnh 7/20/2007. */
|
| - sym = ada_find_any_symbol (name);
|
| + sym = ada_find_any_type_symbol (name);
|
| if (sym != NULL && strstr (SYMBOL_LINKAGE_NAME (sym), "___XR") != NULL)
|
| return sym;
|
| else
|
| @@ -7011,7 +7113,7 @@ find_old_style_renaming_symbol (const char *name, struct block *block)
|
| qualified. This means we need to prepend the function name
|
| as well as adding the ``___XR'' suffix to build the name of
|
| the associated renaming symbol. */
|
| - char *function_name = SYMBOL_LINKAGE_NAME (function_sym);
|
| + const char *function_name = SYMBOL_LINKAGE_NAME (function_sym);
|
| /* Function names sometimes contain suffixes used
|
| for instance to qualify nested subprograms. When building
|
| the XR type name, we need to make sure that this suffix is
|
| @@ -7050,7 +7152,7 @@ find_old_style_renaming_symbol (const char *name, struct block *block)
|
| xsnprintf (rename, rename_len * sizeof (char), "%s___XR", name);
|
| }
|
|
|
| - return ada_find_any_symbol (rename);
|
| + return ada_find_any_type_symbol (rename);
|
| }
|
|
|
| /* Because of GNAT encoding conventions, several GDB symbols may match a
|
| @@ -7091,7 +7193,7 @@ ada_prefer_type (struct type *type0, struct type *type1)
|
| /* The name of TYPE, which is either its TYPE_NAME, or, if that is
|
| null, its TYPE_TAG_NAME. Null if TYPE is null. */
|
|
|
| -char *
|
| +const char *
|
| ada_type_name (struct type *type)
|
| {
|
| if (type == NULL)
|
| @@ -7118,7 +7220,7 @@ find_parallel_type_by_descriptive_type (struct type *type, const char *name)
|
| result = TYPE_DESCRIPTIVE_TYPE (type);
|
| while (result != NULL)
|
| {
|
| - char *result_name = ada_type_name (result);
|
| + const char *result_name = ada_type_name (result);
|
|
|
| if (result_name == NULL)
|
| {
|
| @@ -7170,7 +7272,8 @@ ada_find_parallel_type_with_name (struct type *type, const char *name)
|
| struct type *
|
| ada_find_parallel_type (struct type *type, const char *suffix)
|
| {
|
| - char *name, *typename = ada_type_name (type);
|
| + char *name;
|
| + const char *typename = ada_type_name (type);
|
| int len;
|
|
|
| if (typename == NULL)
|
| @@ -7322,7 +7425,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
|
| {
|
| off = align_value (off, field_alignment (type, f))
|
| + TYPE_FIELD_BITPOS (type, f);
|
| - TYPE_FIELD_BITPOS (rtype, f) = off;
|
| + SET_FIELD_BITPOS (TYPE_FIELD (rtype, f), off);
|
| TYPE_FIELD_BITSIZE (rtype, f) = 0;
|
|
|
| if (ada_is_variant_part (type, f))
|
| @@ -7806,6 +7909,11 @@ to_fixed_array_type (struct type *type0, struct value *dval,
|
| error (_("array type with dynamic size is larger than varsize-limit"));
|
| }
|
|
|
| + /* We want to preserve the type name. This can be useful when
|
| + trying to get the type name of a value that has already been
|
| + printed (for instance, if the user did "print VAR; whatis $". */
|
| + TYPE_NAME (result) = TYPE_NAME (type0);
|
| +
|
| if (constrained_packed_array_p)
|
| {
|
| /* So far, the resulting type has been created as if the original
|
| @@ -7876,7 +7984,7 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
|
| If there is, then it provides the actual size of our type. */
|
| else if (ada_type_name (fixed_record_type) != NULL)
|
| {
|
| - char *name = ada_type_name (fixed_record_type);
|
| + const char *name = ada_type_name (fixed_record_type);
|
| char *xvz_name = alloca (strlen (name) + 7 /* "___XVZ\0" */);
|
| int xvz_found = 0;
|
| LONGEST size;
|
| @@ -8071,7 +8179,7 @@ ada_check_typedef (struct type *type)
|
| return type;
|
| else
|
| {
|
| - char *name = TYPE_TAG_NAME (type);
|
| + const char *name = TYPE_TAG_NAME (type);
|
| struct type *type1 = ada_find_any_type (name);
|
|
|
| if (type1 == NULL)
|
| @@ -8113,9 +8221,11 @@ ada_to_fixed_value_create (struct type *type0, CORE_ADDR address,
|
| struct value *
|
| ada_to_fixed_value (struct value *val)
|
| {
|
| - return ada_to_fixed_value_create (value_type (val),
|
| - value_address (val),
|
| - val);
|
| + val = unwrap_value (val);
|
| + val = ada_to_fixed_value_create (value_type (val),
|
| + value_address (val),
|
| + val);
|
| + return val;
|
| }
|
|
|
|
|
| @@ -8168,7 +8278,7 @@ pos_atr (struct value *arg)
|
|
|
| for (i = 0; i < TYPE_NFIELDS (type); i += 1)
|
| {
|
| - if (v == TYPE_FIELD_BITPOS (type, i))
|
| + if (v == TYPE_FIELD_ENUMVAL (type, i))
|
| return i;
|
| }
|
| error (_("enumeration value is invalid: can't find 'POS"));
|
| @@ -8199,7 +8309,7 @@ value_val_atr (struct type *type, struct value *arg)
|
|
|
| if (pos < 0 || pos >= TYPE_NFIELDS (type))
|
| error (_("argument to 'VAL out of range"));
|
| - return value_from_longest (type, TYPE_FIELD_BITPOS (type, pos));
|
| + return value_from_longest (type, TYPE_FIELD_ENUMVAL (type, pos));
|
| }
|
| else
|
| return value_from_longest (type, value_as_long (arg));
|
| @@ -8677,7 +8787,7 @@ assign_component (struct value *container, struct value *lhs, LONGEST index,
|
| else
|
| {
|
| elt = ada_index_struct_field (index, lhs, 0, value_type (lhs));
|
| - elt = ada_to_fixed_value (unwrap_value (elt));
|
| + elt = ada_to_fixed_value (elt);
|
| }
|
|
|
| if (exp->elts[*pos].opcode == OP_AGGREGATE)
|
| @@ -8851,7 +8961,7 @@ aggregate_assign_from_choices (struct value *container,
|
| else
|
| {
|
| int ind;
|
| - char *name;
|
| + const char *name;
|
|
|
| switch (op)
|
| {
|
| @@ -9514,7 +9624,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
|
| else
|
| {
|
| arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
|
| - arg1 = unwrap_value (arg1);
|
| return ada_to_fixed_value (arg1);
|
| }
|
|
|
| @@ -9588,8 +9697,25 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
|
| {
|
| case TYPE_CODE_FUNC:
|
| if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| - return allocate_value (TYPE_TARGET_TYPE (type));
|
| + {
|
| + struct type *rtype = TYPE_TARGET_TYPE (type);
|
| +
|
| + if (TYPE_GNU_IFUNC (type))
|
| + return allocate_value (TYPE_TARGET_TYPE (rtype));
|
| + return allocate_value (rtype);
|
| + }
|
| return call_function_by_hand (argvec[0], nargs, argvec + 1);
|
| + case TYPE_CODE_INTERNAL_FUNCTION:
|
| + if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| + /* We don't know anything about what the internal
|
| + function might return, but we have to return
|
| + something. */
|
| + return value_zero (builtin_type (exp->gdbarch)->builtin_int,
|
| + not_lval);
|
| + else
|
| + return call_internal_function (exp->gdbarch, exp->language_defn,
|
| + argvec[0], nargs, argvec + 1);
|
| +
|
| case TYPE_CODE_STRUCT:
|
| {
|
| int arity;
|
| @@ -9860,7 +9986,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
|
| else if (discrete_type_p (type_arg))
|
| {
|
| struct type *range_type;
|
| - char *name = ada_type_name (type_arg);
|
| + const char *name = ada_type_name (type_arg);
|
|
|
| range_type = NULL;
|
| if (name != NULL && TYPE_CODE (type_arg) != TYPE_CODE_ENUM)
|
| @@ -10343,7 +10469,7 @@ get_var_value (char *name, char *err_msg)
|
| int nsyms;
|
|
|
| nsyms = ada_lookup_symbol_list (name, get_selected_block (0), VAR_DOMAIN,
|
| - &syms);
|
| + &syms, 1);
|
|
|
| if (nsyms != 1)
|
| {
|
| @@ -10392,7 +10518,7 @@ get_int_var_value (char *name, int *flag)
|
| static struct type *
|
| to_fixed_range_type (struct type *raw_type, struct value *dval)
|
| {
|
| - char *name;
|
| + const char *name;
|
| struct type *base_type;
|
| char *subtype_info;
|
|
|
| @@ -10508,37 +10634,6 @@ ada_is_modular_type (struct type *type)
|
| && TYPE_UNSIGNED (subranged_type));
|
| }
|
|
|
| -/* Try to determine the lower and upper bounds of the given modular type
|
| - using the type name only. Return non-zero and set L and U as the lower
|
| - and upper bounds (respectively) if successful. */
|
| -
|
| -int
|
| -ada_modulus_from_name (struct type *type, ULONGEST *modulus)
|
| -{
|
| - char *name = ada_type_name (type);
|
| - char *suffix;
|
| - int k;
|
| - LONGEST U;
|
| -
|
| - if (name == NULL)
|
| - return 0;
|
| -
|
| - /* Discrete type bounds are encoded using an __XD suffix. In our case,
|
| - we are looking for static bounds, which means an __XDLU suffix.
|
| - Moreover, we know that the lower bound of modular types is always
|
| - zero, so the actual suffix should start with "__XDLU_0__", and
|
| - then be followed by the upper bound value. */
|
| - suffix = strstr (name, "__XDLU_0__");
|
| - if (suffix == NULL)
|
| - return 0;
|
| - k = 10;
|
| - if (!ada_scan_number (suffix, k, &U, NULL))
|
| - return 0;
|
| -
|
| - *modulus = (ULONGEST) U + 1;
|
| - return 1;
|
| -}
|
| -
|
| /* Assuming ada_is_modular_type (TYPE), the modulus of TYPE. */
|
|
|
| ULONGEST
|
| @@ -10706,7 +10801,6 @@ static void
|
| ada_exception_support_info_sniffer (void)
|
| {
|
| struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
|
| - struct symbol *sym;
|
|
|
| /* If the exception info is already known, then no need to recompute it. */
|
| if (data->exception_info != NULL)
|
| @@ -10762,7 +10856,7 @@ static int
|
| is_known_support_routine (struct frame_info *frame)
|
| {
|
| struct symtab_and_line sal;
|
| - char *func_name;
|
| + const char *func_name;
|
| enum language func_lang;
|
| int i;
|
|
|
| @@ -10865,7 +10959,7 @@ ada_unhandled_exception_name_addr_from_raise (void)
|
|
|
| while (fi != NULL)
|
| {
|
| - char *func_name;
|
| + const char *func_name;
|
| enum language func_lang;
|
|
|
| find_frame_funname (fi, &func_name, &func_lang, NULL);
|
| @@ -10925,7 +11019,7 @@ static CORE_ADDR
|
| ada_exception_name_addr (enum exception_catchpoint_kind ex,
|
| struct breakpoint *b)
|
| {
|
| - struct gdb_exception e;
|
| + volatile struct gdb_exception e;
|
| CORE_ADDR result = 0;
|
|
|
| TRY_CATCH (e, RETURN_MASK_ERROR)
|
| @@ -11046,7 +11140,8 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
|
| s = cond_string;
|
| TRY_CATCH (e, RETURN_MASK_ERROR)
|
| {
|
| - exp = parse_exp_1 (&s, block_for_pc (bl->address), 0);
|
| + exp = parse_exp_1 (&s, bl->address,
|
| + block_for_pc (bl->address), 0);
|
| }
|
| if (e.reason < 0)
|
| warning (_("failed to reevaluate internal exception condition "
|
| @@ -11520,19 +11615,13 @@ ada_get_next_arg (char **argsp)
|
| char *end;
|
| char *result;
|
|
|
| - /* Skip any leading white space. */
|
| -
|
| - while (isspace (*args))
|
| - args++;
|
| -
|
| + args = skip_spaces (args);
|
| if (args[0] == '\0')
|
| return NULL; /* No more arguments. */
|
|
|
| /* Find the end of the current argument. */
|
|
|
| - end = args;
|
| - while (*end != '\0' && !isspace (*end))
|
| - end++;
|
| + end = skip_to_space (args);
|
|
|
| /* Adjust ARGSP to point to the start of the next argument. */
|
|
|
| @@ -11550,25 +11639,53 @@ ada_get_next_arg (char **argsp)
|
| /* 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
|
| - specified by the user. */
|
| + specified by the user.
|
| + If a condition is found at the end of the arguments, the condition
|
| + expression is stored in COND_STRING (memory must be deallocated
|
| + after use). Otherwise COND_STRING is set to NULL. */
|
|
|
| static void
|
| catch_ada_exception_command_split (char *args,
|
| enum exception_catchpoint_kind *ex,
|
| - char **excep_string)
|
| + char **excep_string,
|
| + char **cond_string)
|
| {
|
| struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
| char *exception_name;
|
| + char *cond = NULL;
|
|
|
| exception_name = ada_get_next_arg (&args);
|
| + if (exception_name != NULL && strcmp (exception_name, "if") == 0)
|
| + {
|
| + /* 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;
|
| + args -= 2;
|
| + }
|
| make_cleanup (xfree, exception_name);
|
|
|
| + /* Check to see if we have a condition. */
|
| +
|
| + args = skip_spaces (args);
|
| + if (strncmp (args, "if", 2) == 0
|
| + && (isspace (args[2]) || args[2] == '\0'))
|
| + {
|
| + args += 2;
|
| + args = skip_spaces (args);
|
| +
|
| + if (args[0] == '\0')
|
| + error (_("Condition missing after `if' keyword"));
|
| + cond = xstrdup (args);
|
| + make_cleanup (xfree, cond);
|
| +
|
| + args += strlen (args);
|
| + }
|
| +
|
| /* Check that we do not have any more arguments. Anything else
|
| is unexpected. */
|
|
|
| - while (isspace (*args))
|
| - args++;
|
| -
|
| if (args[0] != '\0')
|
| error (_("Junk at end of expression"));
|
|
|
| @@ -11592,6 +11709,7 @@ catch_ada_exception_command_split (char *args,
|
| *ex = ex_catch_exception;
|
| *excep_string = exception_name;
|
| }
|
| + *cond_string = cond;
|
| }
|
|
|
| /* Return the name of the symbol on which we should break in order to
|
| @@ -11735,17 +11853,22 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *excep_string,
|
| If the user asked the catchpoint to catch only a specific
|
| exception, then save the exception name in ADDR_STRING.
|
|
|
| + If the user provided a condition, then set COND_STRING to
|
| + that condition expression (the memory must be deallocated
|
| + after use). Otherwise, set COND_STRING to NULL.
|
| +
|
| See ada_exception_sal for a description of all the remaining
|
| function arguments of this function. */
|
|
|
| static struct symtab_and_line
|
| ada_decode_exception_location (char *args, char **addr_string,
|
| char **excep_string,
|
| + char **cond_string,
|
| const struct breakpoint_ops **ops)
|
| {
|
| enum exception_catchpoint_kind ex;
|
|
|
| - catch_ada_exception_command_split (args, &ex, excep_string);
|
| + catch_ada_exception_command_split (args, &ex, excep_string, cond_string);
|
| return ada_exception_sal (ex, *excep_string, addr_string, ops);
|
| }
|
|
|
| @@ -11756,6 +11879,7 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
|
| struct symtab_and_line sal,
|
| char *addr_string,
|
| char *excep_string,
|
| + char *cond_string,
|
| const struct breakpoint_ops *ops,
|
| int tempflag,
|
| int from_tty)
|
| @@ -11767,6 +11891,8 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
|
| ops, tempflag, from_tty);
|
| c->excep_string = excep_string;
|
| create_excep_cond_exprs (c);
|
| + if (cond_string != NULL)
|
| + set_breakpoint_condition (&c->base, cond_string, from_tty);
|
| install_breakpoint (0, &c->base, 1);
|
| }
|
|
|
| @@ -11781,31 +11907,54 @@ catch_ada_exception_command (char *arg, int from_tty,
|
| struct symtab_and_line sal;
|
| char *addr_string = NULL;
|
| char *excep_string = NULL;
|
| + char *cond_string = NULL;
|
| const struct breakpoint_ops *ops = NULL;
|
|
|
| tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
|
|
|
| if (!arg)
|
| arg = "";
|
| - sal = ada_decode_exception_location (arg, &addr_string, &excep_string, &ops);
|
| + sal = ada_decode_exception_location (arg, &addr_string, &excep_string,
|
| + &cond_string, &ops);
|
| create_ada_exception_catchpoint (gdbarch, sal, addr_string,
|
| - excep_string, ops, tempflag, from_tty);
|
| + excep_string, cond_string, ops,
|
| + tempflag, from_tty);
|
| }
|
|
|
| +/* Assuming that ARGS contains the arguments of a "catch assert"
|
| + command, parse those arguments and return a symtab_and_line object
|
| + for a failed assertion catchpoint.
|
| +
|
| + Set ADDR_STRING to the name of the function where the real
|
| + breakpoint that implements the catchpoint is set.
|
| +
|
| + If ARGS contains a condition, set COND_STRING to that condition
|
| + (the memory needs to be deallocated after use). Otherwise, set
|
| + COND_STRING to NULL. */
|
| +
|
| static struct symtab_and_line
|
| ada_decode_assert_location (char *args, char **addr_string,
|
| + char **cond_string,
|
| const struct breakpoint_ops **ops)
|
| {
|
| - /* Check that no argument where provided at the end of the command. */
|
| + args = skip_spaces (args);
|
|
|
| - if (args != NULL)
|
| + /* Check whether a condition was provided. */
|
| + if (strncmp (args, "if", 2) == 0
|
| + && (isspace (args[2]) || args[2] == '\0'))
|
| {
|
| - while (isspace (*args))
|
| - args++;
|
| - if (*args != '\0')
|
| - error (_("Junk at end of arguments."));
|
| + args += 2;
|
| + args = skip_spaces (args);
|
| + if (args[0] == '\0')
|
| + error (_("condition missing after `if' keyword"));
|
| + *cond_string = xstrdup (args);
|
| }
|
|
|
| + /* Otherwise, there should be no other argument at the end of
|
| + the command. */
|
| + else if (args[0] != '\0')
|
| + error (_("Junk at end of arguments."));
|
| +
|
| return ada_exception_sal (ex_catch_assert, NULL, addr_string, ops);
|
| }
|
|
|
| @@ -11819,15 +11968,17 @@ catch_assert_command (char *arg, int from_tty,
|
| int tempflag;
|
| struct symtab_and_line sal;
|
| char *addr_string = NULL;
|
| + char *cond_string = NULL;
|
| const struct breakpoint_ops *ops = NULL;
|
|
|
| tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
|
|
|
| if (!arg)
|
| arg = "";
|
| - sal = ada_decode_assert_location (arg, &addr_string, &ops);
|
| + sal = ada_decode_assert_location (arg, &addr_string, &cond_string, &ops);
|
| create_ada_exception_catchpoint (gdbarch, sal, addr_string,
|
| - NULL, ops, tempflag, from_tty);
|
| + NULL, cond_string, ops, tempflag,
|
| + from_tty);
|
| }
|
| /* Operators */
|
| /* Information about operators given special treatment in functions
|
| @@ -12310,6 +12461,40 @@ static const struct exp_descriptor ada_exp_descriptor = {
|
| ada_evaluate_subexp
|
| };
|
|
|
| +/* Implement the "la_get_symbol_name_cmp" language_defn method
|
| + for Ada. */
|
| +
|
| +static symbol_name_cmp_ftype
|
| +ada_get_symbol_name_cmp (const char *lookup_name)
|
| +{
|
| + if (should_use_wild_match (lookup_name))
|
| + return wild_match;
|
| + else
|
| + return compare_names;
|
| +}
|
| +
|
| +/* Implement the "la_read_var_value" language_defn method for Ada. */
|
| +
|
| +static struct value *
|
| +ada_read_var_value (struct symbol *var, struct frame_info *frame)
|
| +{
|
| + struct block *frame_block = NULL;
|
| + struct symbol *renaming_sym = NULL;
|
| +
|
| + /* The only case where default_read_var_value is not sufficient
|
| + is when VAR is a renaming... */
|
| + if (frame)
|
| + frame_block = get_frame_block (frame, NULL);
|
| + if (frame_block)
|
| + renaming_sym = ada_find_renaming_symbol (var, frame_block);
|
| + if (renaming_sym != NULL)
|
| + return ada_read_renaming_var_value (renaming_sym, frame_block);
|
| +
|
| + /* This is a typical case where we expect the default_read_var_value
|
| + function to work. */
|
| + return default_read_var_value (var, frame);
|
| +}
|
| +
|
| const struct language_defn ada_language_defn = {
|
| "ada", /* Language name */
|
| language_ada,
|
| @@ -12330,6 +12515,7 @@ const struct language_defn ada_language_defn = {
|
| ada_print_typedef, /* Print a typedef using appropriate syntax */
|
| ada_val_print, /* Print a value using appropriate syntax */
|
| ada_value_print, /* Print a top-level value */
|
| + ada_read_var_value, /* la_read_var_value */
|
| NULL, /* Language specific skip_trampoline */
|
| NULL, /* name_of_this */
|
| ada_lookup_symbol_nonlocal, /* Looking up non-local symbols. */
|
| @@ -12346,7 +12532,7 @@ const struct language_defn ada_language_defn = {
|
| ada_print_array_index,
|
| default_pass_by_reference,
|
| c_get_string,
|
| - compare_names,
|
| + ada_get_symbol_name_cmp, /* la_get_symbol_name_cmp */
|
| ada_iterate_over_symbols,
|
| LANG_MAGIC
|
| };
|
|
|