diff options
-rw-r--r-- | gdb/ChangeLog | 22 | ||||
-rw-r--r-- | gdb/ada-lang.c | 43 | ||||
-rw-r--r-- | gdb/dictionary.c | 169 | ||||
-rw-r--r-- | gdb/dictionary.h | 25 |
4 files changed, 200 insertions, 59 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a7dad2647b2..9e5a615b76c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2010-10-06 Paul Hilfinger <hilfinger@adacore.com> + + * ada-lang.c (ada_match_name): Use new API for wild_match. + (wild_match): Change API to be consistent with that of strcmp_iw; + return 0 for a match, and switch operand order. + (full_match): New function. + (ada_add_block_symbols): Use dict_iter_match_{first,next} for + matching to allow use of hashing. + * dictionary.c (struct dict_vector): Generalize iter_name_first, + iter_name_next ot iter_match_first, iter_match_next. + (iter_name_first_hashed): Replace with iter_match_first_hashed. + (iter_name_next_hashed): Replace with iter_match_next_hashed. + (iter_name_first_linear): Replace with iter_match_first_linear. + (iter_name_next_linear): Replace with iter_match_next_linear. + (dict_iter_name_first): Re-implement to use dict_iter_match_first. + (dict_iter_name_next): Re-implement to use dict_iter_match_next. + (dict_iter_match_first): New function. + (dict_iter_match_next): New function. + (dict_hash): New function. + * dictionary.h (dict_iter_match_first, dict_iter_match_next): Declare. + * psymtab.c (ada_lookup_partial_symbol): Use new wild_match API. + 2010-10-06 Doug Evans <dje@google.com> * data-directory/Makefile.in: Remove @host_makefile_frag@, @frags@. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 5fdf8511f00..c111e40356e 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -5062,6 +5062,13 @@ wild_match (const char *name, const char *patn) } } +static int +full_match (const char *sym_name, const char *search_name) +{ + return !ada_match_name (sym_name, search_name, 0); +} + + /* 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. @@ -5086,9 +5093,9 @@ ada_add_block_symbols (struct obstack *obstackp, found_sym = 0; if (wild) { - struct symbol *sym; - - ALL_BLOCK_SYMBOLS (block, iter, sym) + for (sym = dict_iter_match_first (BLOCK_DICT (block), name, + wild_match, &iter); + sym != NULL; sym = dict_iter_match_next (name, wild_match, &iter)) { if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), SYMBOL_DOMAIN (sym), domain) @@ -5110,29 +5117,25 @@ ada_add_block_symbols (struct obstack *obstackp, } else { - ALL_BLOCK_SYMBOLS (block, iter, sym) + for (sym = dict_iter_match_first (BLOCK_DICT (block), name, + full_match, &iter); + sym != NULL; sym = dict_iter_match_next (name, full_match, &iter)) { 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)) - { - if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED) + if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED) + { + if (SYMBOL_IS_ARGUMENT (sym)) + arg_sym = sym; + else { - if (SYMBOL_IS_ARGUMENT (sym)) - arg_sym = sym; - else - { - found_sym = 1; - add_defn_to_vec (obstackp, - fixup_symbol_section (sym, objfile), - block); - } + found_sym = 1; + add_defn_to_vec (obstackp, + fixup_symbol_section (sym, objfile), + block); } - } + } } } } diff --git a/gdb/dictionary.c b/gdb/dictionary.c index e1c2010bc1c..f3ac3069adb 100644 --- a/gdb/dictionary.c +++ b/gdb/dictionary.c @@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" +#include <ctype.h> #include "gdb_obstack.h" #include "symtab.h" #include "buildsym.h" @@ -116,11 +117,15 @@ struct dict_vector struct dict_iterator *iterator); struct symbol *(*iterator_next) (struct dict_iterator *iterator); /* Functions to iterate over symbols with a given name. */ - struct symbol *(*iter_name_first) (const struct dictionary *dict, + struct symbol *(*iter_match_first) (const struct dictionary *dict, const char *name, + int (*equiv) (const char *, + const char *), + struct dict_iterator *iterator); + struct symbol *(*iter_match_next) (const char *name, + int (*equiv) (const char *, + const char *), struct dict_iterator *iterator); - struct symbol *(*iter_name_next) (const char *name, - struct dict_iterator *iterator); /* A size function, for maint print symtabs. */ int (*size) (const struct dictionary *dict); }; @@ -236,12 +241,18 @@ static struct symbol *iterator_first_hashed (const struct dictionary *dict, static struct symbol *iterator_next_hashed (struct dict_iterator *iterator); -static struct symbol *iter_name_first_hashed (const struct dictionary *dict, - const char *name, +static struct symbol *iter_match_first_hashed (const struct dictionary *dict, + const char *name, + int (*compare) (const char *, + const char *), struct dict_iterator *iterator); -static struct symbol *iter_name_next_hashed (const char *name, - struct dict_iterator *iterator); +static struct symbol *iter_match_next_hashed (const char *name, + int (*compare) (const char *, + const char *), + struct dict_iterator *iterator); + +static unsigned int dict_hash (const char *string); /* Functions only for DICT_HASHED. */ @@ -264,12 +275,16 @@ static struct symbol *iterator_first_linear (const struct dictionary *dict, static struct symbol *iterator_next_linear (struct dict_iterator *iterator); -static struct symbol *iter_name_first_linear (const struct dictionary *dict, - const char *name, - struct dict_iterator *iterator); +static struct symbol *iter_match_first_linear (const struct dictionary *dict, + const char *name, + int (*compare) (const char *, + const char *), + struct dict_iterator *iterator); -static struct symbol *iter_name_next_linear (const char *name, - struct dict_iterator *iterator); +static struct symbol *iter_match_next_linear (const char *name, + int (*compare) (const char *, + const char *), + struct dict_iterator *iterator); static int size_linear (const struct dictionary *dict); @@ -289,8 +304,8 @@ static const struct dict_vector dict_hashed_vector = add_symbol_nonexpandable, /* add_symbol */ iterator_first_hashed, /* iterator_first */ iterator_next_hashed, /* iterator_next */ - iter_name_first_hashed, /* iter_name_first */ - iter_name_next_hashed, /* iter_name_next */ + iter_match_first_hashed, /* iter_name_first */ + iter_match_next_hashed, /* iter_name_next */ size_hashed, /* size */ }; @@ -301,8 +316,8 @@ static const struct dict_vector dict_hashed_expandable_vector = add_symbol_hashed_expandable, /* add_symbol */ iterator_first_hashed, /* iterator_first */ iterator_next_hashed, /* iterator_next */ - iter_name_first_hashed, /* iter_name_first */ - iter_name_next_hashed, /* iter_name_next */ + iter_match_first_hashed, /* iter_name_first */ + iter_match_next_hashed, /* iter_name_next */ size_hashed_expandable, /* size */ }; @@ -313,8 +328,8 @@ static const struct dict_vector dict_linear_vector = add_symbol_nonexpandable, /* add_symbol */ iterator_first_linear, /* iterator_first */ iterator_next_linear, /* iterator_next */ - iter_name_first_linear, /* iter_name_first */ - iter_name_next_linear, /* iter_name_next */ + iter_match_first_linear, /* iter_name_first */ + iter_match_next_linear, /* iter_name_next */ size_linear, /* size */ }; @@ -325,8 +340,8 @@ static const struct dict_vector dict_linear_expandable_vector = add_symbol_linear_expandable, /* add_symbol */ iterator_first_linear, /* iterator_first */ iterator_next_linear, /* iterator_next */ - iter_name_first_linear, /* iter_name_first */ - iter_name_next_linear, /* iter_name_next */ + iter_match_first_linear, /* iter_name_first */ + iter_match_next_linear, /* iter_name_next */ size_linear, /* size */ }; @@ -516,14 +531,31 @@ dict_iter_name_first (const struct dictionary *dict, const char *name, struct dict_iterator *iterator) { - return (DICT_VECTOR (dict))->iter_name_first (dict, name, iterator); + return dict_iter_match_first (dict, name, strcmp_iw, iterator); } struct symbol * dict_iter_name_next (const char *name, struct dict_iterator *iterator) { + return dict_iter_match_next (name, strcmp_iw, iterator); +} + +struct symbol * +dict_iter_match_first (const struct dictionary *dict, + const char *name, + int (*compare) (const char *, const char *), + struct dict_iterator *iterator) +{ + return (DICT_VECTOR (dict))->iter_match_first (dict, name, compare, iterator); +} + +struct symbol * +dict_iter_match_next (const char *name, + int (*compare) (const char *, const char *), + struct dict_iterator *iterator) +{ return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) - ->iter_name_next (name, iterator); + ->iter_match_next (name, compare, iterator); } int @@ -614,12 +646,12 @@ iterator_hashed_advance (struct dict_iterator *iterator) } static struct symbol * -iter_name_first_hashed (const struct dictionary *dict, - const char *name, - struct dict_iterator *iterator) +iter_match_first_hashed (const struct dictionary *dict, + const char *name, + int (*compare) (const char *, const char *), + struct dict_iterator *iterator) { - unsigned int hash_index - = msymbol_hash_iw (name) % DICT_HASHED_NBUCKETS (dict); + unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict); struct symbol *sym; DICT_ITERATOR_DICT (iterator) = dict; @@ -632,8 +664,8 @@ iter_name_first_hashed (const struct dictionary *dict, sym != NULL; sym = sym->hash_next) { - /* Warning: the order of arguments to strcmp_iw matters! */ - if (strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) + /* Warning: the order of arguments to compare matters! */ + if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) { break; } @@ -645,7 +677,9 @@ iter_name_first_hashed (const struct dictionary *dict, } static struct symbol * -iter_name_next_hashed (const char *name, struct dict_iterator *iterator) +iter_match_next_hashed (const char *name, + int (*compare) (const char *, const char *), + struct dict_iterator *iterator) { struct symbol *next; @@ -653,7 +687,7 @@ iter_name_next_hashed (const char *name, struct dict_iterator *iterator) next != NULL; next = next->hash_next) { - if (strcmp_iw (SYMBOL_SEARCH_NAME (next), name) == 0) + if (compare (SYMBOL_SEARCH_NAME (next), name) == 0) break; } @@ -671,8 +705,8 @@ insert_symbol_hashed (struct dictionary *dict, unsigned int hash_index; struct symbol **buckets = DICT_HASHED_BUCKETS (dict); - hash_index = (msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym)) - % DICT_HASHED_NBUCKETS (dict)); + hash_index = + dict_hash (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict); sym->hash_next = buckets[hash_index]; buckets[hash_index] = sym; } @@ -746,6 +780,60 @@ expand_hashtable (struct dictionary *dict) xfree (old_buckets); } +/* Produce an unsigned hash value from STRING0 that is consistent + with strcmp_iw, strcmp, and, at least on Ada symbols, wild_match. + That is, two identifiers equivalent according to any of those three + comparison operators hash to the same value. */ + +static unsigned int +dict_hash (const char *string) +{ + /* The Ada-encoded version of a name P1.P2...Pn has either the form + P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi + are lower-cased identifiers). The <suffix> (which can be empty) + encodes additional information about the denoted entity. This + routine hashes such names to msymbol_hash_iw(Pn). It actually + does this for a superset of both valid Pi and of <suffix>, but + in other cases it simply returns msymbol_hash_iw(STRING0). */ + + unsigned int hash; + int c; + + if (*string == '_' && strncmp (string, "_ada_", 5) == 0) + string += 5; + + hash = 0; + while (*string) + { + switch (*string) + { + case '$': + case '.': + case 'X': + case '(': + return hash; + case ' ': + string += 1; + break; + case '_': + if (string[1] == '_') + { + if (((c = string[2]) < 'a' || c > 'z') && c != 'O') + return hash; + hash = 0; + string += 2; + break; + } + /* FALL THROUGH */ + default: + hash = hash * 67 + *string - 113; + string += 1; + break; + } + } + return hash; +} + /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */ static struct symbol * @@ -769,18 +857,21 @@ iterator_next_linear (struct dict_iterator *iterator) } static struct symbol * -iter_name_first_linear (const struct dictionary *dict, - const char *name, - struct dict_iterator *iterator) +iter_match_first_linear (const struct dictionary *dict, + const char *name, + int (*compare) (const char *, const char *), + struct dict_iterator *iterator) { DICT_ITERATOR_DICT (iterator) = dict; DICT_ITERATOR_INDEX (iterator) = -1; - return iter_name_next_linear (name, iterator); + return iter_match_next_linear (name, compare, iterator); } static struct symbol * -iter_name_next_linear (const char *name, struct dict_iterator *iterator) +iter_match_next_linear (const char *name, + int (*compare) (const char *, const char *), + struct dict_iterator *iterator) { const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); int i, nsyms = DICT_LINEAR_NSYMS (dict); @@ -789,7 +880,7 @@ iter_name_next_linear (const char *name, struct dict_iterator *iterator) for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i) { sym = DICT_LINEAR_SYM (dict, i); - if (strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) + if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) { retval = sym; break; diff --git a/gdb/dictionary.h b/gdb/dictionary.h index 2242a791a18..f7d30350ed7 100644 --- a/gdb/dictionary.h +++ b/gdb/dictionary.h @@ -134,6 +134,31 @@ extern struct symbol *dict_iter_name_first (const struct dictionary *dict, extern struct symbol *dict_iter_name_next (const char *name, struct dict_iterator *iterator); +/* Initialize ITERATOR to point at the first symbol in DICT whose + SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use + the same conventions as strcmp_iw and be compatible with any + dictionary hashing function), and return that first symbol, or NULL + if there are no such symbols. */ + +extern struct symbol *dict_iter_match_first (const struct dictionary *dict, + const char *name, + int (*compare) (const char*, + const char *), + struct dict_iterator *iterator); + +/* Advance ITERATOR to point at the next symbol in DICT whose + SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (see + dict_iter_match_first), or NULL if there are no more such symbols. + Don't call this if you've previously received NULL from + dict_iterator_match_first or dict_iterator_match_next on this + iteration. And don't call it unless ITERATOR was created by a + previous call to dict_iter_match_first with the same NAME and COMPARE. */ + +extern struct symbol *dict_iter_match_next (const char *name, + int (*compare) (const char*, + const char *), + struct dict_iterator *iterator); + /* Return some notion of the size of the dictionary: the number of symbols if we have that, the number of hash buckets otherwise. */ |