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 |
}; |