diff options
author | Paul N. Hilfinger <hilfinger@adacore.com> | 2010-10-07 07:13:51 +0000 |
---|---|---|
committer | Paul N. Hilfinger <hilfinger@adacore.com> | 2010-10-07 07:13:51 +0000 |
commit | 40658b9446ce0507f120bdc69c51c3dfbfd35381 (patch) | |
tree | bf7dc4987b4885a535d3481cf952858337588741 /gdb/ada-lang.c | |
parent | c4d840bdd6f9e19843bd35835cc08e992fe5e1db (diff) | |
download | gdb-40658b9446ce0507f120bdc69c51c3dfbfd35381.zip gdb-40658b9446ce0507f120bdc69c51c3dfbfd35381.tar.gz gdb-40658b9446ce0507f120bdc69c51c3dfbfd35381.tar.bz2 |
Rework symbol searches to move Ada-specific stuff to ada-lang.c.
This is a clean-up of some of our symbol-lookup machinery to pull some
kludgy Ada-specific definitions out of psymtab.c. In place of
map_ada_symtabs and ada_lookup_partial_symbol, we have a method
map_matching_symbols, which searches through all symbol tables and
partial symbol tables looking for a symbol that matches according to
a matching function that is passed as a parameter. This requires some
care, because partial symbol tables speed up searches by binary search,
while full symbol tables use hashing. To call map_matching_symbols, therefore,
you may need to supply both a matching function that is compatible with the
dictionary hash function and an ordering relation that is compatible with
strcmp_iw, which is used to order partial symbol tables.
Having added this general routine to psymtab.c, we use it in ada-lang.c
to rework add_non_local_symbols (now renamed add_nonlocal_symbols).
Changelog:
gdb/
* ada-lang.c (full_match): Declare.
(ada_match_name): Rename to match_name (we should avoid prefixing static
symbols with "ada_").
(match_name): New name for ada_match_name.
(struct ada_psym_data): Remove and replace with...
(struct match_data): User data for map_matching_symbols.
(ada_add_psyms): Remove.
(aux_add_nonlocal_symbols): New function, used as callback for
map_matching_symbols.
(compare_names): Ordering function adopted from strcmp_iw for Ada-encoded
symbols.
(ada_add_non_local_symbols): Rename to add_nonlocal_symbols.
(add_nonlocal_symbols): Renamed from ada_add_non_local_symbols.
Rework to use map_matching_symbols instead of map_ada_symtabs.
(ada_lookup_symbol_list): Use add_nonlocal_symbols.
* psymtab.c: Include dependency on dictionary.h.
(match_partial_symbol): New function.
(ada_lookup_partial_symbol): Remove.
(map_block): New function, auxiliary to map_matching_symbols_psymtab.
(map_matching_symbols_psymtab): New function.
(psym_functions): Replace map_ada_symtabs with map_matching_symbols_psymtab.
* symfile.h: Replace map_ada_symtabs definition with map_matching_symbols.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r-- | gdb/ada-lang.c | 158 |
1 files changed, 121 insertions, 37 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index c111e40..ea71ea2 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -103,6 +103,8 @@ 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 *, @@ -1254,7 +1256,7 @@ ada_la_decode (const char *encoded, int options) either argument is NULL. */ static int -ada_match_name (const char *sym_name, const char *name, int wild) +match_name (const char *sym_name, const char *name, int wild) { if (sym_name == NULL || name == NULL) return 0; @@ -4267,7 +4269,7 @@ ada_lookup_simple_minsym (const char *name) ALL_MSYMBOLS (objfile, msymbol) { - if (ada_match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match) + if (match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match) && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline) return msymbol; } @@ -4627,28 +4629,91 @@ ada_add_local_symbols (struct obstack *obstackp, const char *name, } /* An object of this type is used as the user_data argument when - calling the map_ada_symtabs method. */ + calling the map_matching_symbols method. */ -struct ada_psym_data +struct match_data { + struct objfile *objfile; struct obstack *obstackp; - const char *name; - domain_enum domain; - int global; - int wild_match; + struct symbol *arg_sym; + int found_sym; }; -/* Callback function for map_ada_symtabs. */ +/* A callback for add_matching_symbols that adds SYM, found in BLOCK, + to a list of symbols. DATA0 is a pointer to a struct match_data * + containing the obstack that collects the symbol list, the file that SYM + must come from, a flag indicating whether a non-argument symbol has + been found in the current block, and the last argument symbol + passed in SYM within the current block (if any). When SYM is null, + marking the end of a block, the argument symbol is added if no + other has been found. */ -static void -ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data) +static int +aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0) { - struct ada_psym_data *data = user_data; - const int block_kind = data->global ? GLOBAL_BLOCK : STATIC_BLOCK; + struct match_data *data = (struct match_data *) data0; + + if (sym == NULL) + { + if (!data->found_sym && data->arg_sym != NULL) + add_defn_to_vec (data->obstackp, + fixup_symbol_section (data->arg_sym, data->objfile), + block); + data->found_sym = 0; + data->arg_sym = NULL; + } + else + { + if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED) + return 0; + else if (SYMBOL_IS_ARGUMENT (sym)) + data->arg_sym = sym; + else + { + data->found_sym = 1; + add_defn_to_vec (data->obstackp, + fixup_symbol_section (sym, data->objfile), + block); + } + } + return 0; +} + +/* Compare STRING1 to STRING2, with results as for strcmp. + Compatible with strcmp_iw in that strcmp_iw (STRING1, STRING2) <= 0 + implies compare_names (STRING1, STRING2) (they may differ as to + what symbols compare equal). */ - ada_add_block_symbols (data->obstackp, - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind), - data->name, data->domain, objfile, data->wild_match); +static int +compare_names (const char *string1, const char *string2) +{ + while (*string1 != '\0' && *string2 != '\0') + { + if (isspace (*string1) || isspace (*string2)) + return strcmp_iw_ordered (string1, string2); + if (*string1 != *string2) + break; + string1 += 1; + string2 += 1; + } + switch (*string1) + { + case '(': + return strcmp_iw_ordered (string1, string2); + case '_': + if (*string2 == '\0') + { + if (is_name_suffix (string2)) + return 0; + else + return -1; + } + default: + if (*string2 == '(') + return strcmp_iw_ordered (string1, string2); + else + return *string1 - *string2; + } } /* Add to OBSTACKP all non-local symbols whose name and domain match @@ -4656,27 +4721,43 @@ ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data) symbols if GLOBAL is non-zero, or on STATIC_BLOCK symbols otherwise. */ static void -ada_add_non_local_symbols (struct obstack *obstackp, const char *name, - domain_enum domain, int global, - int is_wild_match) +add_nonlocal_symbols (struct obstack *obstackp, const char *name, + domain_enum domain, int global, + int is_wild_match) { struct objfile *objfile; - struct ada_psym_data data; + struct match_data data; data.obstackp = obstackp; - data.name = name; - data.domain = domain; - data.global = global; - data.wild_match = is_wild_match; + data.arg_sym = NULL; ALL_OBJFILES (objfile) - { - if (objfile->sf) - objfile->sf->qf->map_ada_symtabs (objfile, wild_match, is_name_suffix, - ada_add_psyms, name, - global, domain, - is_wild_match, &data); - } + { + data.objfile = objfile; + + if (is_wild_match) + objfile->sf->qf->map_matching_symbols (name, domain, objfile, global, + aux_add_nonlocal_symbols, &data, + wild_match, NULL); + else + objfile->sf->qf->map_matching_symbols (name, domain, objfile, global, + aux_add_nonlocal_symbols, &data, + full_match, compare_names); + } + + if (num_defns_collected (obstackp) == 0 && global && !is_wild_match) + { + ALL_OBJFILES (objfile) + { + char *name1 = alloca (strlen (name) + sizeof ("_ada_")); + strcpy (name1, "_ada_"); + strcpy (name1 + sizeof ("_ada_") - 1, name); + data.objfile = objfile; + objfile->sf->qf->map_matching_symbols (name1, domain, objfile, global, + aux_add_nonlocal_symbols, &data, + full_match, compare_names); + } + } } /* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing @@ -4753,15 +4834,15 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, /* Search symbols from all global blocks. */ - ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 1, - wild_match); + add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 1, + wild_match); /* 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) - ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 0, - wild_match); + add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 0, + wild_match); done: ndefns = num_defns_collected (&symbol_list_obstack); @@ -5062,10 +5143,13 @@ wild_match (const char *name, const char *patn) } } +/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from + informational suffix. */ + static int full_match (const char *sym_name, const char *search_name) { - return !ada_match_name (sym_name, search_name, 0); + return !match_name (sym_name, search_name, 0); } @@ -5118,7 +5202,7 @@ ada_add_block_symbols (struct obstack *obstackp, else { for (sym = dict_iter_match_first (BLOCK_DICT (block), name, - full_match, &iter); + full_match, &iter); sym != NULL; sym = dict_iter_match_next (name, full_match, &iter)) { if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), |