summaryrefslogtreecommitdiff
path: root/gdb/ada-lang.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r--gdb/ada-lang.c728
1 files changed, 374 insertions, 354 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 7126b25b0e..7ec19d29a6 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -104,16 +104,16 @@ static int ada_type_match (struct type *, struct type *, int);
static int ada_args_match (struct symbol *, struct value **, int);
-static int full_match (const char *, const char *);
-
static struct value *make_array_descriptor (struct type *, struct value *);
static void ada_add_block_symbols (struct obstack *,
- const struct block *, const char *,
- domain_enum, struct objfile *, int);
+ const struct block *,
+ const lookup_name_info &lookup_name,
+ domain_enum, struct objfile *);
static void ada_add_all_symbols (struct obstack *, const struct block *,
- const char *, domain_enum, int, int *);
+ const lookup_name_info &lookup_name,
+ domain_enum, int, int *);
static int is_nonfunction (struct block_symbol *, int);
@@ -203,7 +203,7 @@ static int is_name_suffix (const char *);
static int advance_wild_match (const char **, const char *, int);
-static int wild_match (const char *, const char *);
+static bool wild_match (const char *name, const char *patn);
static struct value *ada_coerce_ref (struct value *);
@@ -270,6 +270,10 @@ static void ada_forward_operator_length (struct expression *, int, int *,
int *);
static struct type *ada_find_any_type (const char *name);
+
+static symbol_name_matcher_ftype *ada_get_symbol_name_matcher
+ (const lookup_name_info &lookup_name);
+
/* The result of a symbol lookup to be stored in our symbol cache. */
@@ -976,11 +980,13 @@ const struct ada_opname_map ada_opname_table[] = {
{NULL, NULL}
};
-/* The "encoded" form of DECODED, according to GNAT conventions.
- The result is valid until the next call to ada_encode. */
+/* The "encoded" form of DECODED, according to GNAT conventions. The
+ result is valid until the next call to ada_encode. If
+ THROW_ERRORS, throw an error if invalid operator name is found.
+ Otherwise, return NULL in that case. */
-char *
-ada_encode (const char *decoded)
+static char *
+ada_encode_1 (const char *decoded, bool throw_errors)
{
static char *encoding_buffer = NULL;
static size_t encoding_buffer_size = 0;
@@ -1010,7 +1016,12 @@ ada_encode (const char *decoded)
&& !startswith (p, mapping->decoded); mapping += 1)
;
if (mapping->encoded == NULL)
- error (_("invalid Ada operator name: %s"), p);
+ {
+ if (throw_errors)
+ error (_("invalid Ada operator name: %s"), p);
+ else
+ return NULL;
+ }
strcpy (encoding_buffer + k, mapping->encoded);
k += strlen (mapping->encoded);
break;
@@ -1026,6 +1037,15 @@ ada_encode (const char *decoded)
return encoding_buffer;
}
+/* The "encoded" form of DECODED, according to GNAT conventions.
+ The result is valid until the next call to ada_encode. */
+
+char *
+ada_encode (const char *decoded)
+{
+ return ada_encode_1 (decoded, true);
+}
+
/* Return NAME folded to lower case, or, if surrounded by single
quotes, unfolded, but with the quotes stripped away. Result good
to next call. */
@@ -1490,31 +1510,6 @@ ada_sniff_from_mangled_name (const char *mangled, char **out)
return 0;
}
-/* Returns non-zero iff SYM_NAME matches NAME, ignoring any trailing
- suffixes that encode debugging information or leading _ada_ on
- SYM_NAME (see is_name_suffix commentary for the debugging
- information that is ignored). If WILD, then NAME need only match a
- suffix of SYM_NAME minus the same suffixes. Also returns 0 if
- either argument is NULL. */
-
-static int
-match_name (const char *sym_name, const char *name, int wild)
-{
- if (sym_name == NULL || name == NULL)
- return 0;
- else if (wild)
- return wild_match (sym_name, name) == 0;
- else
- {
- int len_name = strlen (name);
-
- return (strncmp (sym_name, name, len_name) == 0
- && is_name_suffix (sym_name + len_name))
- || (startswith (sym_name, "_ada_")
- && strncmp (sym_name + 5, name, len_name) == 0
- && is_name_suffix (sym_name + len_name + 5));
- }
-}
/* Arrays */
@@ -3587,7 +3582,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
int n_candidates;
n_candidates =
- ada_lookup_symbol_list (ada_encode (ada_decoded_op_name (op)),
+ ada_lookup_symbol_list (ada_decoded_op_name (op),
(struct block *) NULL, VAR_DOMAIN,
&candidates);
i = ada_resolve_function (candidates, n_candidates, argvec, nargs,
@@ -4758,16 +4753,18 @@ cache_symbol (const char *name, domain_enum domain, struct symbol *sym,
/* Symbol Lookup */
-/* Return nonzero if wild matching should be used when searching for
- all symbols matching LOOKUP_NAME.
+/* Return the symbol name match type that should be used 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)
+static symbol_name_match_type
+name_match_type_from_name (const char *lookup_name)
{
- return (strstr (lookup_name, "__") == NULL);
+ return (strstr (lookup_name, "__") == NULL
+ ? symbol_name_match_type::WILD
+ : symbol_name_match_type::FULL);
}
/* Return the result of a standard (literal, C-like) lookup of NAME in
@@ -4937,23 +4934,18 @@ ada_lookup_simple_minsym (const char *name)
struct bound_minimal_symbol result;
struct objfile *objfile;
struct minimal_symbol *msymbol;
- const int wild_match_p = should_use_wild_match (name);
memset (&result, 0, sizeof (result));
- /* 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 (startswith (name, "standard__"))
- name += sizeof ("standard__") - 1;
+ symbol_name_match_type match_type = name_match_type_from_name (name);
+ lookup_name_info lookup_name (name, match_type);
+
+ symbol_name_matcher_ftype *match_name
+ = ada_get_symbol_name_matcher (lookup_name);
ALL_MSYMBOLS (objfile, msymbol)
{
- if (match_name (MSYMBOL_LINKAGE_NAME (msymbol), name, wild_match_p)
+ if (match_name (MSYMBOL_LINKAGE_NAME (msymbol), lookup_name, NULL)
&& MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
{
result.minsym = msymbol;
@@ -4973,8 +4965,8 @@ ada_lookup_simple_minsym (const char *name)
static void
add_symbols_from_enclosing_procs (struct obstack *obstackp,
- const char *name, domain_enum domain,
- int wild_match_p)
+ const lookup_name_info &lookup_name,
+ domain_enum domain)
{
}
@@ -5426,17 +5418,16 @@ remove_irrelevant_renamings (struct block_symbol *syms,
Note: This function assumes that OBSTACKP has 0 (zero) element in it. */
static void
-ada_add_local_symbols (struct obstack *obstackp, const char *name,
- const struct block *block, domain_enum domain,
- int wild_match_p)
+ada_add_local_symbols (struct obstack *obstackp,
+ const lookup_name_info &lookup_name,
+ const struct block *block, domain_enum domain)
{
int block_depth = 0;
while (block != NULL)
{
block_depth += 1;
- ada_add_block_symbols (obstackp, block, name, domain, NULL,
- wild_match_p);
+ ada_add_block_symbols (obstackp, block, lookup_name, domain, NULL);
/* If we found a non-function match, assume that's the one. */
if (is_nonfunction (defns_collected (obstackp, 0),
@@ -5449,7 +5440,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_p);
+ add_symbols_from_enclosing_procs (obstackp, lookup_name, domain);
}
/* An object of this type is used as the user_data argument when
@@ -5503,28 +5494,27 @@ aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0)
return 0;
}
-/* Helper for add_nonlocal_symbols. Find symbols in DOMAIN which are targetted
- by renamings matching NAME in BLOCK. Add these symbols to OBSTACKP. If
- WILD_MATCH_P is nonzero, perform the naming matching in "wild" mode (see
- function "wild_match" for more information). Return whether we found such
- symbols. */
+/* Helper for add_nonlocal_symbols. Find symbols in DOMAIN which are
+ targeted by renamings matching LOOKUP_NAME in BLOCK. Add these
+ symbols to OBSTACKP. Return whether we found such symbols. */
static int
ada_add_block_renamings (struct obstack *obstackp,
const struct block *block,
- const char *name,
- domain_enum domain,
- int wild_match_p)
+ const lookup_name_info &lookup_name,
+ domain_enum domain)
{
struct using_direct *renaming;
int defns_mark = num_defns_collected (obstackp);
+ symbol_name_matcher_ftype *name_match
+ = ada_get_symbol_name_matcher (lookup_name);
+
for (renaming = block_using (block);
renaming != NULL;
renaming = renaming->next)
{
const char *r_name;
- int name_match;
/* Avoid infinite recursions: skip this renaming if we are actually
already traversing it.
@@ -5549,11 +5539,13 @@ ada_add_block_renamings (struct obstack *obstackp,
r_name = (renaming->alias != NULL
? renaming->alias
: renaming->declaration);
- name_match
- = wild_match_p ? wild_match (r_name, name) : strcmp (r_name, name);
- if (name_match == 0)
- ada_add_all_symbols (obstackp, block, renaming->declaration, domain,
- 1, NULL);
+ if (name_match (r_name, lookup_name, NULL))
+ {
+ lookup_name_info decl_lookup_name (renaming->declaration,
+ lookup_name.match_type ());
+ ada_add_all_symbols (obstackp, block, decl_lookup_name, domain,
+ 1, NULL);
+ }
renaming->searched = 0;
}
return num_defns_collected (obstackp) != defns_mark;
@@ -5644,14 +5636,24 @@ compare_names (const char *string1, const char *string2)
return result;
}
+/* Convenience function to get at the Ada encoded lookup name for
+ LOOKUP_NAME, as a C string. */
+
+static const char *
+ada_lookup_name (const lookup_name_info &lookup_name)
+{
+ return lookup_name.ada ().lookup_name ().c_str ();
+}
+
/* Add to OBSTACKP all non-local symbols whose name and domain match
- NAME and DOMAIN respectively. The search is performed on GLOBAL_BLOCK
- symbols if GLOBAL is non-zero, or on STATIC_BLOCK symbols otherwise. */
+ LOOKUP_NAME and DOMAIN respectively. The search is performed on
+ GLOBAL_BLOCK symbols if GLOBAL is non-zero, or on STATIC_BLOCK
+ symbols otherwise. */
static void
-add_nonlocal_symbols (struct obstack *obstackp, const char *name,
- domain_enum domain, int global,
- int is_wild_match)
+add_nonlocal_symbols (struct obstack *obstackp,
+ const lookup_name_info &lookup_name,
+ domain_enum domain, int global)
{
struct objfile *objfile;
struct compunit_symtab *cu;
@@ -5660,50 +5662,57 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
memset (&data, 0, sizeof data);
data.obstackp = obstackp;
+ bool is_wild_match = lookup_name.ada ().wild_match_p ();
+
ALL_OBJFILES (objfile)
{
data.objfile = objfile;
if (is_wild_match)
- objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
+ objfile->sf->qf->map_matching_symbols (objfile, lookup_name.name ().c_str (),
+ domain, global,
aux_add_nonlocal_symbols, &data,
- wild_match, NULL);
+ symbol_name_match_type::WILD,
+ NULL);
else
- objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
+ objfile->sf->qf->map_matching_symbols (objfile, lookup_name.name ().c_str (),
+ domain, global,
aux_add_nonlocal_symbols, &data,
- full_match, compare_names);
+ symbol_name_match_type::FULL,
+ compare_names);
ALL_OBJFILE_COMPUNITS (objfile, cu)
{
const struct block *global_block
= BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK);
- if (ada_add_block_renamings (obstackp, global_block , name, domain,
- is_wild_match))
+ if (ada_add_block_renamings (obstackp, global_block, lookup_name,
+ domain))
data.found_sym = 1;
}
}
if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
{
+ const char *name = ada_lookup_name (lookup_name);
+ std::string name1 = std::string ("<_ada_") + name + '>';
+
ALL_OBJFILES (objfile)
{
- char *name1 = (char *) alloca (strlen (name) + sizeof ("_ada_"));
- strcpy (name1, "_ada_");
- strcpy (name1 + sizeof ("_ada_") - 1, name);
data.objfile = objfile;
- objfile->sf->qf->map_matching_symbols (objfile, name1, domain,
- global,
+ objfile->sf->qf->map_matching_symbols (objfile, name1.c_str (),
+ domain, global,
aux_add_nonlocal_symbols,
&data,
- full_match, compare_names);
+ symbol_name_match_type::FULL,
+ compare_names);
}
}
}
-/* Find symbols in DOMAIN matching NAME, in BLOCK and, if FULL_SEARCH is
- non-zero, enclosing scope and in global scopes, returning the number of
- matches. Add these to OBSTACKP.
+/* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if
+ FULL_SEARCH is non-zero, enclosing scope and in global scopes,
+ returning the number of matches. Add these to OBSTACKP.
When FULL_SEARCH is non-zero, any non-function/non-enumeral
symbol match within the nest of blocks whose innermost member is BLOCK,
@@ -5711,8 +5720,9 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
enclosing blocks is returned). If there are any matches in or
surrounding BLOCK, then these alone are returned.
- Names prefixed with "standard__" are handled specially: "standard__"
- is first stripped off, and only static and global symbols are searched.
+ Names prefixed with "standard__" are handled specially:
+ "standard__" is first stripped off (by the lookup_name
+ constructor), and only static and global symbols are searched.
If MADE_GLOBAL_LOOKUP_P is non-null, set it before return to whether we had
to lookup global symbols. */
@@ -5720,13 +5730,12 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
static void
ada_add_all_symbols (struct obstack *obstackp,
const struct block *block,
- const char *name,
+ const lookup_name_info &lookup_name,
domain_enum domain,
int full_search,
int *made_global_lookup_p)
{
struct symbol *sym;
- const int wild_match_p = should_use_wild_match (name);
if (made_global_lookup_p)
*made_global_lookup_p = 0;
@@ -5738,25 +5747,21 @@ ada_add_all_symbols (struct obstack *obstackp,
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 (startswith (name, "standard__"))
- {
- block = NULL;
- name = name + sizeof ("standard__") - 1;
- }
+ if (lookup_name.ada ().standard_p ())
+ block = NULL;
/* Check the non-global symbols. If we have ANY match, then we're done. */
if (block != NULL)
{
if (full_search)
- ada_add_local_symbols (obstackp, name, block, domain, wild_match_p);
+ ada_add_local_symbols (obstackp, lookup_name, block, domain);
else
{
/* In the !full_search case we're are being called by
ada_iterate_over_symbols, and we don't want to search
superblocks. */
- ada_add_block_symbols (obstackp, block, name, domain, NULL,
- wild_match_p);
+ ada_add_block_symbols (obstackp, block, lookup_name, domain, NULL);
}
if (num_defns_collected (obstackp) > 0 || !full_search)
return;
@@ -5766,10 +5771,11 @@ ada_add_all_symbols (struct obstack *obstackp,
already performed this search before. If we have, then return
the same result. */
- if (lookup_cached_symbol (name, domain, &sym, &block))
+ if (lookup_cached_symbol (ada_lookup_name (lookup_name),
+ domain, &sym, &block))
{
if (sym != NULL)
- add_defn_to_vec (obstackp, sym, block);
+ add_defn_to_vec (obstackp, sym, block);
return;
}
@@ -5778,17 +5784,17 @@ ada_add_all_symbols (struct obstack *obstackp,
/* Search symbols from all global blocks. */
- add_nonlocal_symbols (obstackp, name, domain, 1, wild_match_p);
+ add_nonlocal_symbols (obstackp, lookup_name, domain, 1);
/* 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 (obstackp) == 0)
- add_nonlocal_symbols (obstackp, name, domain, 0, wild_match_p);
+ add_nonlocal_symbols (obstackp, lookup_name, domain, 0);
}
-/* Find symbols in DOMAIN matching NAME, in BLOCK and, if full_search is
- non-zero, enclosing scope and in global scopes, returning the number of
+/* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if FULL_SEARCH
+ is non-zero, enclosing scope and in global scopes, returning the number of
matches.
Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples,
indicating the symbols found and the blocks and symbol tables (if
@@ -5805,19 +5811,19 @@ ada_add_all_symbols (struct obstack *obstackp,
is first stripped off, and only static and global symbols are searched. */
static int
-ada_lookup_symbol_list_worker (const char *name, const struct block *block,
+ada_lookup_symbol_list_worker (const lookup_name_info &lookup_name,
+ const struct block *block,
domain_enum domain,
struct block_symbol **results,
int full_search)
{
- const int wild_match_p = should_use_wild_match (name);
int syms_from_global_search;
int ndefns;
obstack_free (&symbol_list_obstack, NULL);
obstack_init (&symbol_list_obstack);
- ada_add_all_symbols (&symbol_list_obstack, block, name, domain,
- full_search, &syms_from_global_search);
+ ada_add_all_symbols (&symbol_list_obstack, block, lookup_name,
+ domain, full_search, &syms_from_global_search);
ndefns = num_defns_collected (&symbol_list_obstack);
*results = defns_collected (&symbol_list_obstack, 1);
@@ -5825,32 +5831,37 @@ ada_lookup_symbol_list_worker (const char *name, const struct block *block,
ndefns = remove_extra_symbols (*results, ndefns);
if (ndefns == 0 && full_search && syms_from_global_search)
- cache_symbol (name, domain, NULL, NULL);
+ cache_symbol (ada_lookup_name (lookup_name), domain, NULL, NULL);
if (ndefns == 1 && full_search && syms_from_global_search)
- cache_symbol (name, domain, (*results)[0].symbol, (*results)[0].block);
+ cache_symbol (ada_lookup_name (lookup_name), domain,
+ (*results)[0].symbol, (*results)[0].block);
ndefns = remove_irrelevant_renamings (*results, ndefns, block);
return ndefns;
}
-/* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing scope and
+/* Find symbols in DOMAIN matching NAME, in BLOCK and enclosing scope and
in global scopes, returning the number of matches, and setting *RESULTS
to a vector of (SYM,BLOCK) tuples.
See ada_lookup_symbol_list_worker for further details. */
int
-ada_lookup_symbol_list (const char *name0, const struct block *block0,
+ada_lookup_symbol_list (const char *name, const struct block *block,
domain_enum domain, struct block_symbol **results)
{
- return ada_lookup_symbol_list_worker (name0, block0, domain, results, 1);
+ symbol_name_match_type name_match_type = name_match_type_from_name (name);
+ lookup_name_info lookup_name (name, name_match_type);
+
+ return ada_lookup_symbol_list_worker (lookup_name, block, domain, results, 1);
}
/* Implementation of the la_iterate_over_symbols method. */
static void
ada_iterate_over_symbols
- (const struct block *block, const char *name, domain_enum domain,
+ (const struct block *block, const lookup_name_info &name,
+ domain_enum domain,
gdb::function_view<symbol_found_callback_ftype> callback)
{
int ndefs, i;
@@ -5864,24 +5875,6 @@ ada_iterate_over_symbols
}
}
-/* If NAME is the name of an entity, return a string that should
- be used to look that entity up in Ada units.
-
- NAME can have any form that the "break" or "print" commands might
- recognize. In other words, it does not have to be the "natural"
- name, or the "encoded" name. */
-
-std::string
-ada_name_for_lookup (const char *name)
-{
- int nlen = strlen (name);
-
- if (name[0] == '<' && name[nlen - 1] == '>')
- return std::string (name + 1, nlen - 2);
- else
- return ada_encode (ada_fold_name (name));
-}
-
/* 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.
@@ -5897,10 +5890,19 @@ ada_lookup_encoded_symbol (const char *name, const struct block *block,
struct block_symbol *candidates;
int n_candidates;
+ /* Since we already have an encoded name, wrap it in '<>' to force a
+ verbatim match. Otherwise, if the name happens to not look like
+ an encoded name (because it doesn't include a "__"),
+ ada_lookup_name_info would re-encode/fold it again, and that
+ would e.g., incorrectly lowercase object renaming names like
+ "R28b" -> "r28b". */
+ std::string verbatim = std::string ("<") + name + '>';
+
gdb_assert (info != NULL);
memset (info, 0, sizeof (struct block_symbol));
- n_candidates = ada_lookup_symbol_list (name, block, domain, &candidates);
+ n_candidates = ada_lookup_symbol_list (verbatim.c_str (), block,
+ domain, &candidates);
if (n_candidates == 0)
return;
@@ -6181,11 +6183,12 @@ advance_wild_match (const char **namep, const char *name0, int target0)
return 1;
}
-/* Return 0 iff NAME encodes a name of the form prefix.PATN. Ignores any
- informational suffixes of NAME (i.e., for which is_name_suffix is
- true). Assumes that PATN is a lower-cased Ada simple name. */
+/* Return true iff NAME encodes a name of the form prefix.PATN.
+ Ignores any informational suffixes of NAME (i.e., for which
+ is_name_suffix is true). Assumes that PATN is a lower-cased Ada
+ simple name. */
-static int
+static bool
wild_match (const char *name, const char *patn)
{
const char *p;
@@ -6201,39 +6204,49 @@ wild_match (const char *name, const char *patn)
if (*p != *name)
break;
if (*p == '\0' && is_name_suffix (name))
- return match != name0 && !is_valid_name_for_wild_match (name0);
+ return match == name0 || is_valid_name_for_wild_match (name0);
if (name[-1] == '_')
name -= 1;
}
if (!advance_wild_match (&name, name0, *patn))
- return 1;
+ return false;
}
}
-/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from
- informational suffix. */
+/* Returns true iff symbol name SYM_NAME matches SEARCH_NAME, ignoring
+ any trailing suffixes that encode debugging information or leading
+ _ada_ on SYM_NAME (see is_name_suffix commentary for the debugging
+ information that is ignored). */
-static int
+static bool
full_match (const char *sym_name, const char *search_name)
{
- return !match_name (sym_name, search_name, 0);
-}
+ size_t search_name_len = strlen (search_name);
+
+ if (strncmp (sym_name, search_name, search_name_len) == 0
+ && is_name_suffix (sym_name + search_name_len))
+ return true;
+
+ if (startswith (sym_name, "_ada_")
+ && strncmp (sym_name + 5, search_name, search_name_len) == 0
+ && is_name_suffix (sym_name + search_name_len + 5))
+ return true;
+ return false;
+}
-/* Add symbols from BLOCK matching identifier NAME in DOMAIN to
- vector *defn_symbols, updating the list of symbols in OBSTACKP
- (if necessary). If WILD, treat as NAME with a wildcard prefix.
- OBJFILE is the section containing BLOCK. */
+/* Add symbols from BLOCK matching LOOKUP_NAME in DOMAIN to vector
+ *defn_symbols, updating the list of symbols in OBSTACKP (if
+ necessary). OBJFILE is the section containing BLOCK. */
static void
ada_add_block_symbols (struct obstack *obstackp,
- const struct block *block, const char *name,
- domain_enum domain, struct objfile *objfile,
- int wild)
+ const struct block *block,
+ const lookup_name_info &lookup_name,
+ domain_enum domain, struct objfile *objfile)
{
struct block_iterator iter;
- int name_len = strlen (name);
/* A matching argument symbol, if any. */
struct symbol *arg_sym;
/* Set true when we find a matching non-argument symbol. */
@@ -6242,56 +6255,31 @@ ada_add_block_symbols (struct obstack *obstackp,
arg_sym = NULL;
found_sym = 0;
- if (wild)
+ for (sym = block_iter_match_first (block, lookup_name, &iter);
+ sym != NULL;
+ sym = block_iter_match_next (lookup_name, &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)
- && wild_match (SYMBOL_LINKAGE_NAME (sym), name) == 0)
- {
- 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);
- }
- }
- }
- }
- else
- {
- 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))
- {
- 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);
- }
- }
- }
- }
+ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
+ SYMBOL_DOMAIN (sym), domain))
+ {
+ 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);
+ }
+ }
+ }
}
/* Handle renamings. */
- if (ada_add_block_renamings (obstackp, block, name, domain, wild))
+ if (ada_add_block_renamings (obstackp, block, lookup_name, domain))
found_sym = 1;
if (!found_sym && arg_sym != NULL)
@@ -6301,10 +6289,13 @@ ada_add_block_symbols (struct obstack *obstackp,
block);
}
- if (!wild)
+ if (!lookup_name.ada ().wild_match_p ())
{
arg_sym = NULL;
found_sym = 0;
+ const std::string &ada_lookup_name = lookup_name.ada ().lookup_name ();
+ const char *name = ada_lookup_name.c_str ();
+ size_t name_len = ada_lookup_name.size ();
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
@@ -6355,51 +6346,39 @@ ada_add_block_symbols (struct obstack *obstackp,
/* 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_P is set.
- ENCODED_P should be set if TEXT represents the start of a symbol name
- in its encoded form. */
+/* See symtab.h. */
-static const char *
-symbol_completion_match (const char *sym_name,
- const char *text, int text_len,
- int wild_match_p, int encoded_p)
+bool
+ada_lookup_name_info::matches
+ (const char *sym_name,
+ symbol_name_match_type match_type,
+ completion_match *comp_match) const
{
- const int verbatim_match = (text[0] == '<');
- int match = 0;
-
- if (verbatim_match)
- {
- /* Strip the leading angle bracket. */
- text = text + 1;
- text_len--;
- }
+ bool match = false;
+ const char *text = m_encoded_name.c_str ();
+ size_t text_len = m_encoded_name.size ();
/* First, test against the fully qualified name of the symbol. */
if (strncmp (sym_name, text, text_len) == 0)
- match = 1;
+ match = true;
- if (match && !encoded_p)
+ if (match && !m_encoded_p)
{
/* 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;
+ bool has_angle_bracket;
sym_name = ada_decode (sym_name);
has_angle_bracket = (sym_name[0] == '<');
- match = (has_angle_bracket == verbatim_match);
+ match = (has_angle_bracket == m_verbatim_p);
sym_name = sym_name_copy;
}
- if (match && !verbatim_match)
+ if (match && !m_verbatim_p)
{
/* When doing non-verbatim match, another check that needs to
be done is to verify that the potentially matching symbol name
@@ -6410,12 +6389,12 @@ symbol_completion_match (const char *sym_name,
for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++);
if (*tmp != '\0')
- match = 0;
+ match = false;
}
/* Second: Try wild matching... */
- if (!match && wild_match_p)
+ if (!match && m_wild_match_p)
{
/* Since we are doing wild matching, this means that TEXT
may represent an unqualified symbol name. We therefore must
@@ -6423,91 +6402,48 @@ symbol_completion_match (const char *sym_name,
sym_name = ada_unqualified_name (ada_decode (sym_name));
if (strncmp (sym_name, text, text_len) == 0)
- match = 1;
+ match = true;
}
- /* Finally: If we found a mach, prepare the result to return. */
+ /* Finally: If we found a match, prepare the result to return. */
if (!match)
- return NULL;
-
- if (verbatim_match)
- sym_name = add_angle_brackets (sym_name);
-
- if (!encoded_p)
- sym_name = ada_decode (sym_name);
-
- return sym_name;
-}
-
-/* A companion function to ada_collect_symbol_completion_matches().
- 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 added as a completion match to TRACKER.
-
- 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_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). */
-
-static void
-symbol_completion_add (completion_tracker &tracker,
- const char *sym_name,
- const char *text, int text_len,
- const char *orig_text, const char *word,
- int wild_match_p, int encoded_p)
-{
- const char *match = symbol_completion_match (sym_name, text, text_len,
- wild_match_p, encoded_p);
- char *completion;
+ return false;
- if (match == NULL)
- return;
+ if (comp_match != NULL)
+ {
+ std::string &match_str = comp_match->storage ();
- /* We found a match, so add the appropriate completion to the given
- string vector. */
+ if (!m_encoded_p)
+ {
+ match_str = ada_decode (sym_name);
+ comp_match->set_match (match_str.c_str ());
+ }
+ else
+ {
+ if (m_verbatim_p)
+ match_str = add_angle_brackets (sym_name);
+ else
+ match_str = sym_name;
- if (word == orig_text)
- {
- completion = (char *) xmalloc (strlen (match) + 5);
- strcpy (completion, match);
- }
- else if (word > orig_text)
- {
- /* Return some portion of sym_name. */
- completion = (char *) xmalloc (strlen (match) + 5);
- strcpy (completion, match + (word - orig_text));
- }
- else
- {
- /* Return some of ORIG_TEXT plus sym_name. */
- completion = (char *) xmalloc (strlen (match) + (orig_text - word) + 5);
- strncpy (completion, word, orig_text - word);
- completion[orig_text - word] = '\0';
- strcat (completion, match);
+ comp_match->set_match (match_str.c_str ());
+ }
}
- tracker.add_completion (gdb::unique_xmalloc_ptr<char> (completion));
+ return true;
}
-/* Add the list of possible symbol names completing TEXT0 to TRACKER.
+/* Add the list of possible symbol names completing TEXT to TRACKER.
WORD is the entire command on which completion is made. */
static void
ada_collect_symbol_completion_matches (completion_tracker &tracker,
complete_symbol_mode mode,
- const char *text0, const char *word,
+ symbol_name_match_type name_match_type,
+ const char *text, const char *word,
enum type_code code)
{
- char *text;
int text_len;
- int wild_match_p;
- int encoded_p;
struct symbol *sym;
struct compunit_symtab *s;
struct minimal_symbol *msymbol;
@@ -6519,39 +6455,15 @@ ada_collect_symbol_completion_matches (completion_tracker &tracker,
gdb_assert (code == TYPE_CODE_UNDEF);
- if (text0[0] == '<')
- {
- text = xstrdup (text0);
- make_cleanup (xfree, text);
- text_len = strlen (text);
- wild_match_p = 0;
- encoded_p = 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]);
+ text_len = strlen (text);
- 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_p = (strchr (text0, '.') == NULL && !encoded_p);
- }
+ lookup_name_info lookup_name (std::string (text, text_len),
+ name_match_type, true);
/* First, look at the partial symtab symbols. */
expand_symtabs_matching (NULL,
- [&] (const char *symname)
- {
- return symbol_completion_match (symname,
- text, text_len,
- wild_match_p,
- encoded_p);
- },
+ lookup_name,
+ NULL,
NULL,
ALL_DOMAIN);
@@ -6563,9 +6475,12 @@ ada_collect_symbol_completion_matches (completion_tracker &tracker,
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- symbol_completion_add (tracker, MSYMBOL_LINKAGE_NAME (msymbol),
- text, text_len, text0, word, wild_match_p,
- encoded_p);
+
+ completion_list_add_name (tracker,
+ MSYMBOL_LANGUAGE (msymbol),
+ MSYMBOL_LINKAGE_NAME (msymbol),
+ lookup_name,
+ text, text_len, text, word);
}
/* Search upwards from currently selected frame (so that we can
@@ -6578,9 +6493,11 @@ ada_collect_symbol_completion_matches (completion_tracker &tracker,
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- symbol_completion_add (tracker, SYMBOL_LINKAGE_NAME (sym),
- text, text_len, text0, word,
- wild_match_p, encoded_p);
+ completion_list_add_name (tracker,
+ SYMBOL_LANGUAGE (sym),
+ SYMBOL_LINKAGE_NAME (sym),
+ lookup_name,
+ text, text_len, text, word);
}
}
@@ -6593,9 +6510,11 @@ ada_collect_symbol_completion_matches (completion_tracker &tracker,
b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), GLOBAL_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- symbol_completion_add (tracker, SYMBOL_LINKAGE_NAME (sym),
- text, text_len, text0, word,
- wild_match_p, encoded_p);
+ completion_list_add_name (tracker,
+ SYMBOL_LANGUAGE (sym),
+ SYMBOL_LINKAGE_NAME (sym),
+ lookup_name,
+ text, text_len, text, word);
}
}
@@ -6608,9 +6527,11 @@ ada_collect_symbol_completion_matches (completion_tracker &tracker,
continue;
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- symbol_completion_add (tracker, SYMBOL_LINKAGE_NAME (sym),
- text, text_len, text0, word,
- wild_match_p, encoded_p);
+ completion_list_add_name (tracker,
+ SYMBOL_LANGUAGE (sym),
+ SYMBOL_LINKAGE_NAME (sym),
+ lookup_name,
+ text, text_len, text, word);
}
}
@@ -11583,11 +11504,12 @@ scan_discrim_bound (const char *str, int k, struct value *dval, LONGEST * px,
static struct value *
get_var_value (const char *name, const char *err_msg)
{
- struct block_symbol *syms;
- int nsyms;
+ lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
- nsyms = ada_lookup_symbol_list (name, get_selected_block (0), VAR_DOMAIN,
- &syms);
+ struct block_symbol *syms;
+ int nsyms = ada_lookup_symbol_list_worker (lookup_name,
+ get_selected_block (0),
+ VAR_DOMAIN, &syms, 1);
if (nsyms != 1)
{
@@ -13260,6 +13182,7 @@ ada_add_global_exceptions (compiled_regex *preg,
regular expression used to do the matching refers to the natural
name. So match against the decoded name. */
expand_symtabs_matching (NULL,
+ lookup_name_info::match_any (),
[&] (const char *search_name)
{
const char *decoded = ada_decode (search_name);
@@ -13859,16 +13782,113 @@ static const struct exp_descriptor ada_exp_descriptor = {
ada_evaluate_subexp
};
-/* Implement the "la_get_symbol_name_cmp" language_defn method
- for Ada. */
+/* symbol_name_matcher_ftype adapter for wild_match. */
+
+static bool
+do_wild_match (const char *symbol_search_name,
+ const lookup_name_info &lookup_name,
+ completion_match *match)
+{
+ return wild_match (symbol_search_name, ada_lookup_name (lookup_name));
+}
+
+/* symbol_name_matcher_ftype adapter for full_match. */
+
+static bool
+do_full_match (const char *symbol_search_name,
+ const lookup_name_info &lookup_name,
+ completion_match *match)
+{
+ return full_match (symbol_search_name, ada_lookup_name (lookup_name));
+}
+
+/* Build the Ada lookup name for LOOKUP_NAME. */
+
+ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
+{
+ const std::string &user_name = lookup_name.name ();
+
+ if (user_name[0] == '<')
+ {
+ if (user_name.back () == '>')
+ m_encoded_name = user_name.substr (1, user_name.size () - 2);
+ else
+ m_encoded_name = user_name.substr (1, user_name.size () - 1);
+ m_encoded_p = true;
+ m_verbatim_p = true;
+ m_wild_match_p = false;
+ m_standard_p = false;
+ }
+ else
+ {
+ m_verbatim_p = false;
+
+ m_encoded_p = user_name.find ("__") != std::string::npos;
+
+ if (!m_encoded_p)
+ {
+ const char *folded = ada_fold_name (user_name.c_str ());
+ const char *encoded = ada_encode_1 (folded, false);
+ if (encoded != NULL)
+ m_encoded_name = encoded;
+ else
+ m_encoded_name = user_name;
+ }
+ else
+ m_encoded_name = user_name;
+
+ /* Handle the 'package Standard' special case. See description
+ of m_standard_p. */
+ if (startswith (m_encoded_name.c_str (), "standard__"))
+ {
+ m_encoded_name = m_encoded_name.substr (sizeof ("standard__") - 1);
+ m_standard_p = true;
+ }
+ else
+ m_standard_p = false;
-static symbol_name_cmp_ftype
-ada_get_symbol_name_cmp (const char *lookup_name)
+ /* 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. Also, in the standard__ special case always do
+ non-wild matching. */
+ m_wild_match_p
+ = (lookup_name.match_type () != symbol_name_match_type::FULL
+ && !m_encoded_p
+ && !m_standard_p
+ && user_name.find ('.') == std::string::npos);
+ }
+}
+
+/* symbol_name_matcher_ftype method for Ada. This only handles
+ completion mode. */
+
+static bool
+ada_symbol_name_matches (const char *symbol_search_name,
+ const lookup_name_info &lookup_name,
+ completion_match *match)
{
- if (should_use_wild_match (lookup_name))
- return wild_match;
+ return lookup_name.ada ().matches (symbol_search_name,
+ lookup_name.match_type (),
+ match);
+}
+
+/* Implement the "la_get_symbol_name_matcher" language_defn method for
+ Ada. */
+
+static symbol_name_matcher_ftype *
+ada_get_symbol_name_matcher (const lookup_name_info &lookup_name)
+{
+ if (lookup_name.completion_mode ())
+ return ada_symbol_name_matches;
else
- return compare_names;
+ {
+ if (lookup_name.ada ().wild_match_p ())
+ return do_wild_match;
+ else
+ return do_full_match;
+ }
}
/* Implement the "la_read_var_value" language_defn method for Ada. */
@@ -13939,7 +13959,7 @@ extern const struct language_defn ada_language_defn = {
default_pass_by_reference,
c_get_string,
c_watch_location_expression,
- ada_get_symbol_name_cmp, /* la_get_symbol_name_cmp */
+ ada_get_symbol_name_matcher, /* la_get_symbol_name_matcher */
ada_iterate_over_symbols,
default_search_name_hash,
&ada_varobj_ops,