#include "valprint.h"
#include "source.h"
#include "observer.h"
+#include "vec.h"
#ifndef ADA_RETAIN_DOTS
#define ADA_RETAIN_DOTS 0
#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
#endif
-
static void extract_string (CORE_ADDR addr, char *buf);
static void modify_general_field (char *, LONGEST, int, int);
static void ada_add_block_symbols (struct obstack *,
struct block *, const char *,
- domain_enum, struct objfile *,
- struct symtab *, int);
+ domain_enum, struct objfile *, int);
static int is_nonfunction (struct ada_symbol_info *, int);
static void add_defn_to_vec (struct obstack *, struct symbol *,
- struct block *, struct symtab *);
+ struct block *);
static int num_defns_collected (struct obstack *);
struct objfile *);
static struct type *to_static_fixed_type (struct type *);
+static struct type *static_unwrap_type (struct type *type);
static struct value *unwrap_value (struct value *);
/* Utilities */
+/* Given DECODED_NAME a string holding a symbol name in its
+ decoded form (ie using the Ada dotted notation), returns
+ its unqualified name. */
+
+static const char *
+ada_unqualified_name (const char *decoded_name)
+{
+ const char *result = strrchr (decoded_name, '.');
+
+ if (result != NULL)
+ result++; /* Skip the dot... */
+ else
+ result = decoded_name;
+
+ return result;
+}
+
+/* Return a string starting with '<', followed by STR, and '>'.
+ The result is good until the next call. */
+
+static char *
+add_angle_brackets (const char *str)
+{
+ static char *result = NULL;
+
+ xfree (result);
+ result = (char *) xmalloc ((strlen (str) + 3) * sizeof (char));
+
+ sprintf (result, "<%s>", str);
+ return result;
+}
static char *
ada_get_gdb_completer_word_break_characters (void)
{
struct symbol *sym;
struct block **blocks;
- const char *raw_name = ada_type_name (ada_check_typedef (type));
- char *name = (char *) alloca (strlen (raw_name) + 1);
- char *tail = strstr (raw_name, "___XP");
+ char *raw_name = ada_type_name (ada_check_typedef (type));
+ char *name;
+ char *tail;
struct type *shadow_type;
long bits;
int i, n;
+ if (!raw_name)
+ raw_name = ada_type_name (desc_base_type (type));
+
+ if (!raw_name)
+ return NULL;
+
+ name = (char *) alloca (strlen (raw_name) + 1);
+ tail = strstr (raw_name, "___XP");
type = desc_base_type (type);
memcpy (name, raw_name, tail - raw_name);
return NULL;
}
- if (BITS_BIG_ENDIAN && ada_is_modular_type (value_type (arr)))
+ if (gdbarch_bits_big_endian (current_gdbarch)
+ && ada_is_modular_type (value_type (arr)))
{
/* This is a (right-justified) modular type representing a packed
array with no wrapper. In order to interpret the value through
int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8;
/* Transmit bytes from least to most significant; delta is the direction
the indices move. */
- int delta = BITS_BIG_ENDIAN ? -1 : 1;
+ int delta = gdbarch_bits_big_endian (current_gdbarch) ? -1 : 1;
type = ada_check_typedef (type);
v = allocate_value (type);
bytes = (unsigned char *) (valaddr + offset);
}
- else if (value_lazy (obj))
+ else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
{
v = value_at (type,
VALUE_ADDRESS (obj) + value_offset (obj) + offset);
memset (unpacked, 0, TYPE_LENGTH (type));
return v;
}
- else if (BITS_BIG_ENDIAN)
+ else if (gdbarch_bits_big_endian (current_gdbarch))
{
src = len - 1;
if (has_negatives (type)
targ_offset %= HOST_CHAR_BIT;
source += src_offset / HOST_CHAR_BIT;
src_offset %= HOST_CHAR_BIT;
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (current_gdbarch))
{
accum = (unsigned char) *source;
source += 1;
{
int len = (value_bitpos (toval)
+ bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ int from_size;
char *buffer = (char *) alloca (len);
struct value *val;
CORE_ADDR to_addr = VALUE_ADDRESS (toval) + value_offset (toval);
fromval = value_cast (type, fromval);
read_memory (to_addr, buffer, len);
- if (BITS_BIG_ENDIAN)
+ from_size = value_bitsize (fromval);
+ if (from_size == 0)
+ from_size = TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT;
+ if (gdbarch_bits_big_endian (current_gdbarch))
move_bits (buffer, value_bitpos (toval),
- value_contents (fromval),
- TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT -
- bits, bits);
+ value_contents (fromval), from_size - bits, bits);
else
move_bits (buffer, value_bitpos (toval), value_contents (fromval),
0, bits);
else
bits = value_bitsize (component);
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (current_gdbarch))
move_bits (value_contents_writeable (container) + offset_in_container,
value_bitpos (container) + bit_offset_in_container,
value_contents (val),
bounds type. It works for other arrays with bounds supplied by
run-time quantities other than discriminants. */
-LONGEST
+static LONGEST
ada_array_bound_from_type (struct type * arr_type, int n, int which,
struct type ** typep)
{
index_type_desc = ada_find_parallel_type (type, "___XA");
if (index_type_desc == NULL)
{
- struct type *range_type;
struct type *index_type;
while (n > 1)
n -= 1;
}
- range_type = TYPE_INDEX_TYPE (type);
- index_type = TYPE_TARGET_TYPE (range_type);
- if (TYPE_CODE (index_type) == TYPE_CODE_UNDEF)
- index_type = builtin_type_long;
+ index_type = TYPE_INDEX_TYPE (type);
if (typep != NULL)
*typep = index_type;
+
+ /* The index type is either a range type or an enumerated type.
+ For the range type, we have some macros that allow us to
+ extract the value of the low and high bounds. But they
+ do now work for enumerated types. The expressions used
+ below work for both range and enum types. */
return
(LONGEST) (which == 0
- ? TYPE_LOW_BOUND (range_type)
- : TYPE_HIGH_BOUND (range_type));
+ ? TYPE_FIELD_BITPOS (index_type, 0)
+ : TYPE_FIELD_BITPOS (index_type,
+ TYPE_NFIELDS (index_type) - 1));
}
else
{
struct type *index_type =
to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, n - 1),
NULL, TYPE_OBJFILE (arr_type));
+
if (typep != NULL)
- *typep = TYPE_TARGET_TYPE (index_type);
+ *typep = index_type;
+
return
(LONGEST) (which == 0
? TYPE_LOW_BOUND (index_type)
}
/* Given that arr is an array value, returns the lower bound of the
- nth index (numbering from 1) if which is 0, and the upper bound if
- which is 1. This routine will also work for arrays with bounds
+ nth index (numbering from 1) if WHICH is 0, and the upper bound if
+ WHICH is 1. This routine will also work for arrays with bounds
supplied by run-time quantities other than discriminants. */
struct value *
case LOC_REGISTER:
case LOC_ARG:
case LOC_REF_ARG:
- case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_LOCAL:
- case LOC_LOCAL_ARG:
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
goto FoundNonType;
default:
break;
break;
case OP_TYPE:
+ case OP_REGISTER:
return NULL;
}
int *chosen = (int *) alloca (sizeof (int) * nsyms);
int n_chosen;
int first_choice = (max_results == 1) ? 1 : 2;
+ const char *select_mode = multiple_symbols_select_mode ();
if (max_results < 1)
error (_("Request to select 0 symbols!"));
if (nsyms <= 1)
return nsyms;
+ if (select_mode == multiple_symbols_cancel)
+ error (_("\
+canceled because the command is ambiguous\n\
+See set/show multiple-symbol."));
+
+ /* If select_mode is "all", then return all possible symbols.
+ Only do that if more than one symbol can be selected, of course.
+ Otherwise, display the menu as usual. */
+ if (select_mode == multiple_symbols_all && max_results > 1)
+ return nsyms;
+
printf_unfiltered (_("[0] cancel\n"));
if (max_results > 1)
printf_unfiltered (_("[1] all\n"));
int is_all_choice, char *annotation_suffix)
{
char *args;
- const char *prompt;
+ char *prompt;
int n_chosen;
int first_choice = is_all_choice ? 2 : 1;
prompt = getenv ("PS2");
if (prompt == NULL)
- prompt = ">";
-
- printf_unfiltered (("%s "), prompt);
- gdb_flush (gdb_stdout);
+ prompt = "> ";
- args = command_line_input ((char *) NULL, 0, annotation_suffix);
+ args = command_line_input (prompt, 0, annotation_suffix);
if (args == NULL)
error_no_arg (_("one or more choice numbers"));
if (gdbarch_frame_align_p (current_gdbarch))
*sp = gdbarch_frame_align (current_gdbarch, *sp);
}
+ VALUE_LVAL (val) = lval_memory;
write_memory (VALUE_ADDRESS (val), value_contents_raw (val), len);
}
allocating any necessary descriptors (fat pointers), or copies of
values not residing in memory, updating it as needed. */
-static struct value *
-convert_actual (struct value *actual, struct type *formal_type0,
- CORE_ADDR *sp)
+struct value *
+ada_convert_actual (struct value *actual, struct type *formal_type0,
+ CORE_ADDR *sp)
{
struct type *actual_type = ada_check_typedef (value_type (actual));
struct type *formal_type = ada_check_typedef (formal_type0);
if (ada_is_array_descriptor_type (formal_target)
&& TYPE_CODE (actual_target) == TYPE_CODE_ARRAY)
return make_array_descriptor (formal_type, actual, sp);
- else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR)
+ else if (TYPE_CODE (formal_type) == TYPE_CODE_PTR
+ || TYPE_CODE (formal_type) == TYPE_CODE_REF)
{
+ struct value *result;
if (TYPE_CODE (formal_target) == TYPE_CODE_ARRAY
&& ada_is_array_descriptor_type (actual_target))
- return desc_data (actual);
+ result = desc_data (actual);
else if (TYPE_CODE (actual_type) != TYPE_CODE_PTR)
{
if (VALUE_LVAL (actual) != lval_memory)
TYPE_LENGTH (actual_type));
actual = ensure_lval (val, sp);
}
- return value_addr (actual);
+ result = value_addr (actual);
}
+ else
+ return actual;
+ return value_cast_pointers (formal_type, result);
}
else if (TYPE_CODE (actual_type) == TYPE_CODE_PTR)
return ada_value_ind (actual);
else
return descriptor;
}
-
-
-/* Assuming a dummy frame has been established on the target, perform any
- conversions needed for calling function FUNC on the NARGS actual
- parameters in ARGS, other than standard C conversions. Does
- nothing if FUNC does not have Ada-style prototype data, or if NARGS
- does not match the number of arguments expected. Use *SP as a
- stack pointer for additional data that must be pushed, updating its
- value as needed. */
-
-void
-ada_convert_actuals (struct value *func, int nargs, struct value *args[],
- CORE_ADDR *sp)
-{
- int i;
-
- if (TYPE_NFIELDS (value_type (func)) == 0
- || nargs != TYPE_NFIELDS (value_type (func)))
- return;
-
- for (i = 0; i < nargs; i += 1)
- args[i] =
- convert_actual (args[i], TYPE_FIELD_TYPE (value_type (func), i), sp);
-}
\f
/* Dummy definitions for an experimental caching module that is not
* used in the public sources. */
static int
lookup_cached_symbol (const char *name, domain_enum namespace,
- struct symbol **sym, struct block **block,
- struct symtab **symtab)
+ struct symbol **sym, struct block **block)
{
return 0;
}
static void
cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
- struct block *block, struct symtab *symtab)
+ struct block *block)
{
}
\f
domain_enum domain)
{
struct symbol *sym;
- struct symtab *symtab;
- if (lookup_cached_symbol (name, domain, &sym, NULL, NULL))
+ if (lookup_cached_symbol (name, domain, &sym, NULL))
return sym;
- sym =
- lookup_symbol_in_language (name, block, domain, language_c, 0, &symtab);
- cache_symbol (name, domain, sym, block_found, symtab);
+ sym = lookup_symbol_in_language (name, block, domain, language_c, 0);
+ cache_symbol (name, domain, sym, block_found);
return sym;
}
static void
add_defn_to_vec (struct obstack *obstackp,
struct symbol *sym,
- struct block *block, struct symtab *symtab)
+ struct block *block)
{
int i;
size_t tmp;
{
prevDefns[i].sym = sym;
prevDefns[i].block = block;
- prevDefns[i].symtab = symtab;
return;
}
}
info.sym = sym;
info.block = block;
- info.symtab = symtab;
obstack_grow (obstackp, &info, sizeof (struct ada_symbol_info));
}
}
{
struct partial_symbol *psym = start[i];
- if (SYMBOL_DOMAIN (psym) == namespace
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
+ SYMBOL_DOMAIN (psym), namespace)
&& wild_match (name, name_len, SYMBOL_LINKAGE_NAME (psym)))
return psym;
}
{
struct partial_symbol *psym = start[i];
- if (SYMBOL_DOMAIN (psym) == namespace)
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
+ SYMBOL_DOMAIN (psym), namespace))
{
int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len);
{
struct partial_symbol *psym = start[i];
- if (SYMBOL_DOMAIN (psym) == namespace)
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
+ SYMBOL_DOMAIN (psym), namespace))
{
int cmp;
case LOC_REGISTER:
case LOC_ARG:
case LOC_REF_ARG:
- case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_LOCAL:
case LOC_TYPEDEF:
- case LOC_LOCAL_ARG:
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
for (j = FIRST_LOCAL_BLOCK;
j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
{
/* 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,SYMTAB) triples,
+ *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
{
block_depth += 1;
ada_add_block_symbols (&symbol_list_obstack, block, name,
- namespace, NULL, NULL, wild_match);
+ namespace, NULL, wild_match);
/* If we found a non-function match, assume that's the one. */
if (is_nonfunction (defns_collected (&symbol_list_obstack, 0),
goto done;
cacheIfUnique = 1;
- if (lookup_cached_symbol (name0, namespace, &sym, &block, &s))
+ if (lookup_cached_symbol (name0, namespace, &sym, &block))
{
if (sym != NULL)
- add_defn_to_vec (&symbol_list_obstack, sym, block, s);
+ add_defn_to_vec (&symbol_list_obstack, sym, block);
goto done;
}
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
ada_add_block_symbols (&symbol_list_obstack, block, name, namespace,
- objfile, s, wild_match);
+ objfile, wild_match);
}
if (namespace == VAR_DOMAIN)
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
ada_add_block_symbols (&symbol_list_obstack, block,
SYMBOL_LINKAGE_NAME (msymbol),
- namespace, objfile, s, wild_match);
+ namespace, objfile, wild_match);
if (num_defns_collected (&symbol_list_obstack) == ndefns0)
{
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
ada_add_block_symbols (&symbol_list_obstack, block,
SYMBOL_LINKAGE_NAME (msymbol),
- namespace, objfile, s,
+ namespace, objfile,
wild_match);
}
}
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
ada_add_block_symbols (&symbol_list_obstack, block, name,
- namespace, objfile, s, wild_match);
+ namespace, objfile, wild_match);
}
}
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
ada_add_block_symbols (&symbol_list_obstack, block, name, namespace,
- objfile, s, wild_match);
+ objfile, wild_match);
}
ALL_PSYMTABS (objfile, ps)
continue;
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
ada_add_block_symbols (&symbol_list_obstack, block, name,
- namespace, objfile, s, wild_match);
+ namespace, objfile, wild_match);
}
}
}
ndefns = remove_extra_symbols (*results, ndefns);
if (ndefns == 0)
- cache_symbol (name0, namespace, NULL, NULL, NULL);
+ cache_symbol (name0, namespace, NULL, NULL);
if (ndefns == 1 && cacheIfUnique)
- cache_symbol (name0, namespace, (*results)[0].sym, (*results)[0].block,
- (*results)[0].symtab);
+ cache_symbol (name0, namespace, (*results)[0].sym, (*results)[0].block);
ndefns = remove_irrelevant_renamings (*results, ndefns, block0);
struct symbol *
ada_lookup_encoded_symbol (const char *name, const struct block *block0,
- domain_enum namespace,
- struct block **block_found, struct symtab **symtab)
+ domain_enum namespace, struct block **block_found)
{
struct ada_symbol_info *candidates;
int n_candidates;
if (block_found != NULL)
*block_found = candidates[0].block;
- if (symtab != NULL)
- {
- *symtab = candidates[0].symtab;
- if (*symtab == NULL && candidates[0].block != NULL)
- {
- struct objfile *objfile;
- struct symtab *s;
- struct block *b;
- struct blockvector *bv;
-
- /* Search the list of symtabs for one which contains the
- address of the start of this block. */
- ALL_PRIMARY_SYMTABS (objfile, s)
- {
- bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- if (BLOCK_START (b) <= BLOCK_START (candidates[0].block)
- && BLOCK_END (b) > BLOCK_START (candidates[0].block))
- {
- *symtab = s;
- return fixup_symbol_section (candidates[0].sym, objfile);
- }
- }
- /* FIXME: brobecker/2004-11-12: I think that we should never
- reach this point. I don't see a reason why we would not
- find a symtab for a given block, so I suggest raising an
- internal_error exception here. Otherwise, we end up
- returning a symbol but no symtab, which certain parts of
- the code that rely (indirectly) on this function do not
- expect, eventually causing a SEGV. */
- return fixup_symbol_section (candidates[0].sym, NULL);
- }
- }
- return candidates[0].sym;
+ return fixup_symbol_section (candidates[0].sym, NULL);
}
/* Return a symbol in DOMAIN matching NAME, in BLOCK0 and enclosing
assignments occur only if the pointers are non-null). */
struct symbol *
ada_lookup_symbol (const char *name, const struct block *block0,
- domain_enum namespace, int *is_a_field_of_this,
- struct symtab **symtab)
+ domain_enum namespace, int *is_a_field_of_this)
{
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, symtab);
+ block0, namespace, NULL);
}
static struct symbol *
ada_lookup_symbol_nonlocal (const char *name,
const char *linkage_name,
const struct block *block,
- const domain_enum domain, struct symtab **symtab)
+ const domain_enum domain)
{
if (linkage_name == NULL)
linkage_name = name;
return ada_lookup_symbol (linkage_name, block_static_block (block), domain,
- NULL, symtab);
+ NULL);
}
names (e.g., XVE) are not included here. Currently, the possible suffixes
are given by either of the regular expression:
- (__[0-9]+)?[.$][0-9]+ [nested subprogram suffix, on platforms such
- as GNU/Linux]
- ___[0-9]+ [nested subprogram suffix, on platforms such as HP/UX]
- _E[0-9]+[bs]$ [protected object entry suffixes]
+ [.$][0-9]+ [nested subprogram suffix, on platforms such as GNU/Linux]
+ ___[0-9]+ [nested subprogram suffix, on platforms such as HP/UX]
+ _E[0-9]+[bs]$ [protected object entry suffixes]
(X[nb]*)?((\$|__)[0-9](_?[0-9]+)|___(JM|LJM|X([FDBUP].*|R[^T]?)))?$
- */
+
+ Also, any leading "__[0-9]+" sequence is skipped before the suffix
+ match is performed. This sequence is used to differentiate homonyms,
+ is an optional part of a valid name suffix. */
static int
is_name_suffix (const char *str)
const char *matching;
const int len = strlen (str);
- /* (__[0-9]+)?\.[0-9]+ */
- matching = str;
+ /* Skip optional leading __[0-9]+. */
+
if (len > 3 && str[0] == '_' && str[1] == '_' && isdigit (str[2]))
{
- matching += 3;
- while (isdigit (matching[0]))
- matching += 1;
- if (matching[0] == '\0')
- return 1;
+ str += 3;
+ while (isdigit (str[0]))
+ str += 1;
}
+
+ /* [.$][0-9]+ */
- if (matching[0] == '.' || matching[0] == '$')
+ if (str[0] == '.' || str[0] == '$')
{
- matching += 1;
+ matching = str + 1;
while (isdigit (matching[0]))
matching += 1;
if (matching[0] == '\0')
}
/* ___[0-9]+ */
+
if (len > 3 && str[0] == '_' && str[1] == '_' && str[2] == '_')
{
matching = str + 3;
str += 1;
}
}
+
if (str[0] == '\000')
return 1;
+
if (str[0] == '_')
{
if (str[1] != '_' || str[2] == '\000')
ada_add_block_symbols (struct obstack *obstackp,
struct block *block, const char *name,
domain_enum domain, struct objfile *objfile,
- struct symtab *symtab, int wild)
+ int wild)
{
struct dict_iterator iter;
int name_len = strlen (name);
struct symbol *sym;
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
- if (SYMBOL_DOMAIN (sym) == domain
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain)
&& wild_match (name, name_len, SYMBOL_LINKAGE_NAME (sym)))
{
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_ARG:
- case LOC_LOCAL_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED_ARG:
- arg_sym = sym;
- break;
- case LOC_UNRESOLVED:
- continue;
- default:
+ if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED)
+ continue;
+ else if (SYMBOL_IS_ARGUMENT (sym))
+ arg_sym = sym;
+ else
+ {
found_sym = 1;
add_defn_to_vec (obstackp,
fixup_symbol_section (sym, objfile),
- block, symtab);
- break;
+ block);
}
}
}
{
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
- if (SYMBOL_DOMAIN (sym) == domain)
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain))
{
int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (sym), name_len);
if (cmp == 0
&& is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len))
{
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_ARG:
- case LOC_LOCAL_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED_ARG:
- arg_sym = sym;
- break;
- case LOC_UNRESOLVED:
- break;
- default:
- found_sym = 1;
- add_defn_to_vec (obstackp,
- fixup_symbol_section (sym, objfile),
- block, symtab);
- break;
- }
+ if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
+ {
+ if (SYMBOL_IS_ARGUMENT (sym))
+ arg_sym = sym;
+ else
+ {
+ found_sym = 1;
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (sym, objfile),
+ block);
+ }
+ }
}
}
}
{
add_defn_to_vec (obstackp,
fixup_symbol_section (arg_sym, objfile),
- block, symtab);
+ block);
}
if (!wild)
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
- if (SYMBOL_DOMAIN (sym) == domain)
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain))
{
int cmp;
if (cmp == 0
&& is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len + 5))
{
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_ARG:
- case LOC_LOCAL_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_REGPARM_ADDR:
- case LOC_BASEREG_ARG:
- case LOC_COMPUTED_ARG:
- arg_sym = sym;
- break;
- case LOC_UNRESOLVED:
- break;
- default:
- found_sym = 1;
- add_defn_to_vec (obstackp,
- fixup_symbol_section (sym, objfile),
- block, symtab);
- break;
- }
+ if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
+ {
+ if (SYMBOL_IS_ARGUMENT (sym))
+ arg_sym = sym;
+ else
+ {
+ found_sym = 1;
+ add_defn_to_vec (obstackp,
+ fixup_symbol_section (sym, objfile),
+ block);
+ }
+ }
}
}
}
{
add_defn_to_vec (obstackp,
fixup_symbol_section (arg_sym, objfile),
- block, symtab);
+ block);
}
}
}
\f
+
+ /* Symbol Completion */
+
+/* If SYM_NAME is a completion candidate for TEXT, return this symbol
+ name in a form that's appropriate for the completion. The result
+ 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
+ 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)
+{
+ char *result;
+ const int verbatim_match = (text[0] == '<');
+ int match = 0;
+
+ if (verbatim_match)
+ {
+ /* Strip the leading angle bracket. */
+ text = text + 1;
+ text_len--;
+ }
+
+ /* First, test against the fully qualified name of the symbol. */
+
+ if (strncmp (sym_name, text, text_len) == 0)
+ match = 1;
+
+ if (match && !encoded)
+ {
+ /* One needed check before declaring a positive match is to verify
+ that iff we are doing a verbatim match, the decoded version
+ of the symbol name starts with '<'. Otherwise, this symbol name
+ is not a suitable completion. */
+ const char *sym_name_copy = sym_name;
+ int has_angle_bracket;
+
+ sym_name = ada_decode (sym_name);
+ has_angle_bracket = (sym_name[0] == '<');
+ match = (has_angle_bracket == verbatim_match);
+ sym_name = sym_name_copy;
+ }
+
+ if (match && !verbatim_match)
+ {
+ /* When doing non-verbatim match, another check that needs to
+ be done is to verify that the potentially matching symbol name
+ does not include capital letters, because the ada-mode would
+ not be able to understand these symbol names without the
+ angle bracket notation. */
+ const char *tmp;
+
+ for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
+ if (*tmp != '\0')
+ match = 0;
+ }
+
+ /* Second: Try wild matching... */
+
+ if (!match && wild_match)
+ {
+ /* Since we are doing wild matching, this means that TEXT
+ may represent an unqualified symbol name. We therefore must
+ also compare TEXT against the unqualified name of the symbol. */
+ sym_name = ada_unqualified_name (ada_decode (sym_name));
+
+ if (strncmp (sym_name, text, text_len) == 0)
+ match = 1;
+ }
+
+ /* Finally: If we found a mach, prepare the result to return. */
+
+ if (!match)
+ return NULL;
+
+ if (verbatim_match)
+ sym_name = add_angle_brackets (sym_name);
+
+ if (!encoded)
+ sym_name = ada_decode (sym_name);
+
+ return sym_name;
+}
+
+typedef char *char_ptr;
+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
+ it is appended at the end of the given string vector SV.
+
+ ORIG_TEXT is the string original string from the user command
+ that needs to be completed. WORD is the entire command on which
+ 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
+ encoded formed (in which case the completion should also be
+ encoded). */
+
+static void
+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)
+{
+ const char *match = symbol_completion_match (sym_name, text, text_len,
+ wild_match, encoded);
+ char *completion;
+
+ if (match == NULL)
+ return;
+
+ /* We found a match, so add the appropriate completion to the given
+ string vector. */
+
+ if (word == orig_text)
+ {
+ completion = xmalloc (strlen (match) + 5);
+ strcpy (completion, match);
+ }
+ else if (word > orig_text)
+ {
+ /* Return some portion of sym_name. */
+ completion = xmalloc (strlen (match) + 5);
+ strcpy (completion, match + (word - orig_text));
+ }
+ else
+ {
+ /* Return some of ORIG_TEXT plus sym_name. */
+ completion = xmalloc (strlen (match) + (orig_text - word) + 5);
+ strncpy (completion, word, orig_text - word);
+ completion[orig_text - word] = '\0';
+ strcat (completion, match);
+ }
+
+ VEC_safe_push (char_ptr, *sv, completion);
+}
+
+/* Return a list of possible symbol names completing TEXT0. The list
+ is NULL terminated. WORD is the entire command on which completion
+ is made. */
+
+static char **
+ada_make_symbol_completion_list (char *text0, char *word)
+{
+ char *text;
+ int text_len;
+ int wild_match;
+ int encoded;
+ VEC(char_ptr) *completions = VEC_alloc (char_ptr, 128);
+ struct symbol *sym;
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct minimal_symbol *msymbol;
+ struct objfile *objfile;
+ struct block *b, *surrounding_static_block = 0;
+ int i;
+ struct dict_iterator iter;
+
+ if (text0[0] == '<')
+ {
+ text = xstrdup (text0);
+ make_cleanup (xfree, text);
+ text_len = strlen (text);
+ wild_match = 0;
+ encoded = 1;
+ }
+ else
+ {
+ text = xstrdup (ada_encode (text0));
+ make_cleanup (xfree, text);
+ text_len = strlen (text);
+ for (i = 0; i < text_len; i++)
+ text[i] = tolower (text[i]);
+
+ encoded = (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);
+ }
+
+ /* First, look at the partial symtab symbols. */
+ ALL_PSYMTABS (objfile, ps)
+ {
+ struct partial_symbol **psym;
+
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin)
+ continue;
+
+ for (psym = objfile->global_psymbols.list + ps->globals_offset;
+ psym < (objfile->global_psymbols.list + ps->globals_offset
+ + ps->n_global_syms); psym++)
+ {
+ QUIT;
+ symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (*psym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+
+ for (psym = objfile->static_psymbols.list + ps->statics_offset;
+ psym < (objfile->static_psymbols.list + ps->statics_offset
+ + ps->n_static_syms); psym++)
+ {
+ QUIT;
+ symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (*psym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
+
+ /* At this point scan through the misc symbol vectors and add each
+ symbol you find to the list. Eventually we want to ignore
+ anything that isn't a text symbol (everything else will be
+ handled by the psymtab code above). */
+
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ QUIT;
+ symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (msymbol),
+ text, text_len, text0, word, wild_match, encoded);
+ }
+
+ /* Search upwards from currently selected frame (so that we can
+ complete on local vars. */
+
+ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ {
+ if (!BLOCK_SUPERBLOCK (b))
+ surrounding_static_block = b; /* For elmin of dups */
+
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
+
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym),
+ text, text_len, text0, word,
+ wild_match, encoded);
+ }
+ }
+
+ /* 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 = malloc (completions_size);
+
+ memcpy (result, VEC_address (char_ptr, completions), completions_size);
+
+ VEC_free (char_ptr, completions);
+ return result;
+ }
+}
+
/* Field Access */
/* Return non-zero if TYPE is a pointer to the GNAT dispatch table used
else
address = unpack_pointer (t, value_contents (arg));
- t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL, address, NULL);
+ t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL, address, NULL, 1);
if (find_struct_field (name, t1, 0,
&field_type, &byte_offset, &bit_offset,
&bit_size, NULL))
{
int others_clause;
int i;
- int disp;
- struct type *discrim_type;
char *discrim_name = ada_variant_discrim_name (var_type);
+ struct value *outer;
+ struct value *discrim;
LONGEST discrim_val;
- disp = 0;
- discrim_type =
- ada_lookup_struct_elt_type (outer_type, discrim_name, 1, 1, &disp);
- if (discrim_type == NULL)
+ outer = value_from_contents_and_address (outer_type, outer_valaddr, 0);
+ discrim = ada_value_struct_elt (outer, discrim_name, 1);
+ if (discrim == NULL)
return -1;
- discrim_val = unpack_long (discrim_type, outer_valaddr + disp);
+ discrim_val = value_as_long (discrim);
others_clause = -1;
for (i = 0; i < TYPE_NFIELDS (var_type); i += 1)
else
dval = dval0;
+ /* Get the fixed type of the field. Note that, in this case, we
+ do not want to get the real type out of the tag: if the current
+ field is the parent part of a tagged record, we will get the
+ tag of the object. Clearly wrong: the real type of the parent
+ is not the real type of the child. We would end up in an infinite
+ loop. */
TYPE_FIELD_TYPE (rtype, f) =
ada_to_fixed_type
(ada_get_base_type
(TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, f))),
cond_offset_host (valaddr, off / TARGET_CHAR_BIT),
- cond_offset_target (address, off / TARGET_CHAR_BIT), dval);
+ cond_offset_target (address, off / TARGET_CHAR_BIT), dval, 0);
TYPE_FIELD_NAME (rtype, f) = TYPE_FIELD_NAME (type, f);
bit_incr = fld_bit_len =
TYPE_LENGTH (TYPE_FIELD_TYPE (rtype, f)) * TARGET_CHAR_BIT;
if (is_dynamic_field (type0, f))
new_type = to_static_fixed_type (TYPE_TARGET_TYPE (field_type));
else
- new_type = to_static_fixed_type (field_type);
+ new_type = static_unwrap_type (field_type);
if (type == type0 && new_type != field_type)
{
TYPE_TARGET_TYPE (type0) = type = alloc_type (TYPE_OBJFILE (type0));
the elements of an array of a tagged type should all be of
the same type specified in the debugging info. No need to
consult the object tag. */
- struct type *elt_type = ada_to_fixed_type (elt_type0, 0, 0, dval);
+ struct type *elt_type = ada_to_fixed_type (elt_type0, 0, 0, dval, 1);
if (elt_type0 == elt_type)
result = type0;
the elements of an array of a tagged type should all be of
the same type specified in the debugging info. No need to
consult the object tag. */
- result = ada_to_fixed_type (ada_check_typedef (elt_type0), 0, 0, dval);
+ result =
+ ada_to_fixed_type (ada_check_typedef (elt_type0), 0, 0, dval, 1);
for (i = TYPE_NFIELDS (index_type_desc) - 1; i >= 0; i -= 1)
{
struct type *range_type =
and may be NULL if there are none, or if the object of type TYPE at
ADDRESS or in VALADDR contains these discriminants.
- In the case of tagged types, this function attempts to locate the object's
- tag and use it to compute the actual type. However, when ADDRESS is null,
- we cannot use it to determine the location of the tag, and therefore
- compute the tagged type's actual type. So we return the tagged type
- without consulting the tag. */
+ If CHECK_TAG is not null, in the case of tagged types, this function
+ attempts to locate the object's tag and use it to compute the actual
+ type. However, when ADDRESS is null, we cannot use it to determine the
+ location of the tag, and therefore compute the tagged type's actual type.
+ So we return the tagged type without consulting the tag. */
-struct type *
-ada_to_fixed_type (struct type *type, const gdb_byte *valaddr,
- CORE_ADDR address, struct value *dval)
+static struct type *
+ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
+ CORE_ADDR address, struct value *dval, int check_tag)
{
type = ada_check_typedef (type);
switch (TYPE_CODE (type))
case TYPE_CODE_STRUCT:
{
struct type *static_type = to_static_fixed_type (type);
-
+ struct type *fixed_record_type =
+ to_fixed_record_type (type, valaddr, address, NULL);
/* If STATIC_TYPE is a tagged type and we know the object's address,
then we can determine its tag, and compute the object's actual
- type from there. */
+ type from there. Note that we have to use the fixed record
+ type (the parent part of the record may have dynamic fields
+ and the way the location of _tag is expressed may depend on
+ them). */
- if (address != 0 && ada_is_tagged_type (static_type, 0))
+ if (check_tag && address != 0 && ada_is_tagged_type (static_type, 0))
{
struct type *real_type =
- type_from_tag (value_tag_from_contents_and_address (static_type,
- valaddr,
- address));
+ type_from_tag (value_tag_from_contents_and_address
+ (fixed_record_type,
+ valaddr,
+ address));
if (real_type != NULL)
- type = real_type;
+ return to_fixed_record_type (real_type, valaddr, address, NULL);
}
- return to_fixed_record_type (type, valaddr, address, NULL);
+ return fixed_record_type;
}
case TYPE_CODE_ARRAY:
return to_fixed_array_type (type, dval, 1);
}
}
+/* The same as ada_to_fixed_type_1, except that it preserves the type
+ if it is a TYPE_CODE_TYPEDEF of a type that is already fixed.
+ ada_to_fixed_type_1 would return the type referenced by TYPE. */
+
+struct type *
+ada_to_fixed_type (struct type *type, const gdb_byte *valaddr,
+ CORE_ADDR address, struct value *dval, int check_tag)
+
+{
+ struct type *fixed_type =
+ ada_to_fixed_type_1 (type, valaddr, address, dval, check_tag);
+
+ if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
+ && TYPE_TARGET_TYPE (type) == fixed_type)
+ return type;
+
+ return fixed_type;
+}
+
/* A standard (static-sized) type corresponding as well as possible to
TYPE0, but based on no runtime data. */
struct type *
ada_check_typedef (struct type *type)
{
+ if (type == NULL)
+ return NULL;
+
CHECK_TYPEDEF (type);
if (type == NULL || TYPE_CODE (type) != TYPE_CODE_ENUM
|| !TYPE_STUB (type)
ada_to_fixed_value_create (struct type *type0, CORE_ADDR address,
struct value *val0)
{
- struct type *type = ada_to_fixed_type (type0, 0, address, NULL);
+ struct type *type = ada_to_fixed_type (type0, 0, address, NULL, 1);
if (type == type0 && val0 != NULL)
return val0;
else
struct type *type = ada_check_typedef (value_type (val));
if (ada_is_aligner_type (type))
{
- struct value *v = value_struct_elt (&val, NULL, "F",
- NULL, "internal structure");
+ struct value *v = ada_value_struct_elt (val, "F", 0);
struct type *val_type = ada_check_typedef (value_type (v));
if (ada_type_name (val_type) == NULL)
TYPE_NAME (val_type) = ada_type_name (type);
coerce_unspec_val_to_type
(val, ada_to_fixed_type (raw_real_type, 0,
VALUE_ADDRESS (val) + value_offset (val),
- NULL));
+ NULL, 1));
}
}
if (ada_is_direct_array_type (value_type (arg1))
|| ada_is_direct_array_type (value_type (arg2)))
{
+ /* Automatically dereference any array reference before
+ we attempt to perform the comparison. */
+ arg1 = ada_coerce_ref (arg1);
+ arg2 = ada_coerce_ref (arg2);
+
arg1 = ada_coerce_to_simple_array (arg1);
arg2 = ada_coerce_to_simple_array (arg2);
if (TYPE_CODE (value_type (arg1)) != TYPE_CODE_ARRAY
return arg1;
return ada_value_assign (arg1, arg1);
}
- arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
+ /* Force the evaluation of the rhs ARG2 to the type of the lhs ARG1,
+ except if the lhs of our assignment is a convenience variable.
+ In the case of assigning to a convenience variable, the lhs
+ should be exactly the result of the evaluation of the rhs. */
+ type = value_type (arg1);
+ if (VALUE_LVAL (arg1) == lval_internalvar)
+ type = NULL;
+ arg2 = evaluate_subexp (type, exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
if (ada_is_fixed_point_type (value_type (arg1)))
case OP_VAR_VALUE:
*pos -= 1;
+
+ /* Tagged types are a little special in the fact that the real type
+ is dynamic and can only be determined by inspecting the object
+ value. So even if we're support to do an EVAL_AVOID_SIDE_EFFECTS
+ evaluation, we force an EVAL_NORMAL evaluation for tagged types. */
+ if (noside == EVAL_AVOID_SIDE_EFFECTS
+ && ada_is_tagged_type (SYMBOL_TYPE (exp->elts[pc + 2].symbol), 1))
+ noside = EVAL_NORMAL;
+
if (noside == EVAL_SKIP)
{
*pos += 4;
if (arity != nargs)
error (_("wrong number of subscripts; expecting %d"), arity);
if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return allocate_value (ada_aligned_type (type));
+ return value_zero (ada_aligned_type (type), lval_memory);
return
unwrap_value (ada_value_subscript
(argvec[0], nargs, argvec + 1));
if (type == NULL)
error (_("element type of array unknown"));
else
- return allocate_value (ada_aligned_type (type));
+ return value_zero (ada_aligned_type (type), lval_memory);
}
return
unwrap_value (ada_value_subscript
if (type == NULL)
error (_("element type of array unknown"));
else
- return allocate_value (ada_aligned_type (type));
+ return value_zero (ada_aligned_type (type), lval_memory);
}
return
unwrap_value (ada_value_ptr_subscript (argvec[0], type,
ada_val_print, /* Print a value using appropriate syntax */
ada_value_print, /* Print a top-level value */
NULL, /* Language specific skip_trampoline */
- NULL, /* value_of_this */
+ NULL, /* name_of_this */
ada_lookup_symbol_nonlocal, /* Looking up non-local symbols. */
basic_lookup_transparent_type, /* lookup_transparent_type */
ada_la_decode, /* Language specific symbol demangler */
0, /* c-style arrays */
1, /* String lower bound */
ada_get_gdb_completer_word_break_characters,
+ ada_make_symbol_completion_list,
ada_language_arch_info,
ada_print_array_index,
default_pass_by_reference,