X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdictionary.c;h=da8b7da2085ed775b4cd80c7c83d3ff243171a33;hb=e98ee8c458f3a8405eb93e71b00f801b4bbe3635;hp=29816921d91fb6cc96ccfd8bf022696dc0ed29c7;hpb=0963b4bd458eab010b3b19c9ffd8eb790f2cd06c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dictionary.c b/gdb/dictionary.c index 29816921d9..da8b7da208 100644 --- a/gdb/dictionary.c +++ b/gdb/dictionary.c @@ -1,7 +1,6 @@ /* Routines for name->symbol lookups in GDB. - Copyright (C) 2003, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 2003-2018 Free Software Foundation, Inc. Contributed by David Carlton and by Kealia, Inc. @@ -26,8 +25,8 @@ #include "gdb_obstack.h" #include "symtab.h" #include "buildsym.h" -#include "gdb_assert.h" #include "dictionary.h" +#include "safe-ctype.h" /* This file implements dictionaries, which are tables that associate symbols to names. They are represented by an opaque type 'struct @@ -117,11 +116,9 @@ struct dict_vector struct symbol *(*iterator_next) (struct dict_iterator *iterator); /* Functions to iterate over symbols with a given name. */ struct symbol *(*iter_match_first) (const struct dictionary *dict, - const char *name, - symbol_compare_ftype *equiv, + const lookup_name_info &name, struct dict_iterator *iterator); - struct symbol *(*iter_match_next) (const char *name, - symbol_compare_ftype *equiv, + struct symbol *(*iter_match_next) (const lookup_name_info &name, struct dict_iterator *iterator); /* A size function, for maint print symtabs. */ int (*size) (const struct dictionary *dict); @@ -167,6 +164,7 @@ struct dictionary_linear_expandable struct dictionary { + const struct language_defn *language; const struct dict_vector *vector; union { @@ -181,6 +179,7 @@ struct dictionary /* Accessor macros. */ #define DICT_VECTOR(d) (d)->vector +#define DICT_LANGUAGE(d) (d)->language /* These can be used for DICT_HASHED_EXPANDABLE, too. */ @@ -239,16 +238,12 @@ static struct symbol *iterator_first_hashed (const struct dictionary *dict, static struct symbol *iterator_next_hashed (struct dict_iterator *iterator); static struct symbol *iter_match_first_hashed (const struct dictionary *dict, - const char *name, - symbol_compare_ftype *compare, + const lookup_name_info &name, struct dict_iterator *iterator); -static struct symbol *iter_match_next_hashed (const char *name, - symbol_compare_ftype *compare, +static struct symbol *iter_match_next_hashed (const lookup_name_info &name, struct dict_iterator *iterator); -static unsigned int dict_hash (const char *string); - /* Functions only for DICT_HASHED. */ static int size_hashed (const struct dictionary *dict); @@ -271,12 +266,10 @@ static struct symbol *iterator_first_linear (const struct dictionary *dict, static struct symbol *iterator_next_linear (struct dict_iterator *iterator); static struct symbol *iter_match_first_linear (const struct dictionary *dict, - const char *name, - symbol_compare_ftype *compare, + const lookup_name_info &name, struct dict_iterator *iterator); -static struct symbol *iter_match_next_linear (const char *name, - symbol_compare_ftype *compare, +static struct symbol *iter_match_next_linear (const lookup_name_info &name, struct dict_iterator *iterator); static int size_linear (const struct dictionary *dict); @@ -350,12 +343,11 @@ static void expand_hashtable (struct dictionary *dict); /* The creation functions. */ -/* Create a dictionary implemented via a fixed-size hashtable. All - memory it uses is allocated on OBSTACK; the environment is - initialized from SYMBOL_LIST. */ +/* See dictionary.h. */ struct dictionary * dict_create_hashed (struct obstack *obstack, + enum language language, const struct pending *symbol_list) { struct dictionary *retval; @@ -363,8 +355,9 @@ dict_create_hashed (struct obstack *obstack, struct symbol **buckets; const struct pending *list_counter; - retval = obstack_alloc (obstack, sizeof (struct dictionary)); + retval = XOBNEW (obstack, struct dictionary); DICT_VECTOR (retval) = &dict_hashed_vector; + DICT_LANGUAGE (retval) = language_def (language); /* Calculate the number of symbols, and allocate space for them. */ for (list_counter = symbol_list; @@ -375,7 +368,7 @@ dict_create_hashed (struct obstack *obstack, } nbuckets = DICT_HASHTABLE_SIZE (nsyms); DICT_HASHED_NBUCKETS (retval) = nbuckets; - buckets = obstack_alloc (obstack, nbuckets * sizeof (struct symbol *)); + buckets = XOBNEWVEC (obstack, struct symbol *, nbuckets); memset (buckets, 0, nbuckets * sizeof (struct symbol *)); DICT_HASHED_BUCKETS (retval) = buckets; @@ -393,33 +386,28 @@ dict_create_hashed (struct obstack *obstack, return retval; } -/* Create a dictionary implemented via a hashtable that grows as - necessary. The dictionary is initially empty; to add symbols to - it, call dict_add_symbol(). Call dict_free() when you're done with - it. */ +/* See dictionary.h. */ extern struct dictionary * -dict_create_hashed_expandable (void) +dict_create_hashed_expandable (enum language language) { - struct dictionary *retval; + struct dictionary *retval = XNEW (struct dictionary); - retval = xmalloc (sizeof (struct dictionary)); DICT_VECTOR (retval) = &dict_hashed_expandable_vector; + DICT_LANGUAGE (retval) = language_def (language); DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY; - DICT_HASHED_BUCKETS (retval) = xcalloc (DICT_EXPANDABLE_INITIAL_CAPACITY, - sizeof (struct symbol *)); + DICT_HASHED_BUCKETS (retval) = XCNEWVEC (struct symbol *, + DICT_EXPANDABLE_INITIAL_CAPACITY); DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0; return retval; } -/* Create a dictionary implemented via a fixed-size array. All memory - it uses is allocated on OBSTACK; the environment is initialized - from the SYMBOL_LIST. The symbols are ordered in the same order - that they're found in SYMBOL_LIST. */ +/* See dictionary.h. */ struct dictionary * dict_create_linear (struct obstack *obstack, + enum language language, const struct pending *symbol_list) { struct dictionary *retval; @@ -427,8 +415,9 @@ dict_create_linear (struct obstack *obstack, struct symbol **syms; const struct pending *list_counter; - retval = obstack_alloc (obstack, sizeof (struct dictionary)); + retval = XOBNEW (obstack, struct dictionary); DICT_VECTOR (retval) = &dict_linear_vector; + DICT_LANGUAGE (retval) = language_def (language); /* Calculate the number of symbols, and allocate space for them. */ for (list_counter = symbol_list; @@ -438,7 +427,7 @@ dict_create_linear (struct obstack *obstack, nsyms += list_counter->nsyms; } DICT_LINEAR_NSYMS (retval) = nsyms; - syms = obstack_alloc (obstack, nsyms * sizeof (struct symbol *)); + syms = XOBNEWVEC (obstack, struct symbol *, nsyms ); DICT_LINEAR_SYMS (retval) = syms; /* Now fill in the symbols. Start filling in from the back, so as @@ -458,24 +447,19 @@ dict_create_linear (struct obstack *obstack, return retval; } -/* Create a dictionary implemented via an array that grows as - necessary. The dictionary is initially empty; to add symbols to - it, call dict_add_symbol(). Call dict_free() when you're done with - it. */ +/* See dictionary.h. */ struct dictionary * -dict_create_linear_expandable (void) +dict_create_linear_expandable (enum language language) { - struct dictionary *retval; + struct dictionary *retval = XNEW (struct dictionary); - retval = xmalloc (sizeof (struct dictionary)); DICT_VECTOR (retval) = &dict_linear_expandable_vector; + DICT_LANGUAGE (retval) = language_def (language); DICT_LINEAR_NSYMS (retval) = 0; - DICT_LINEAR_EXPANDABLE_CAPACITY (retval) - = DICT_EXPANDABLE_INITIAL_CAPACITY; + DICT_LINEAR_EXPANDABLE_CAPACITY (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY; DICT_LINEAR_SYMS (retval) - = xmalloc (DICT_LINEAR_EXPANDABLE_CAPACITY (retval) - * sizeof (struct symbol *)); + = XNEWVEC (struct symbol *, DICT_LINEAR_EXPANDABLE_CAPACITY (retval)); return retval; } @@ -499,6 +483,22 @@ dict_add_symbol (struct dictionary *dict, struct symbol *sym) (DICT_VECTOR (dict))->add_symbol (dict, sym); } +/* Utility to add a list of symbols to a dictionary. + DICT must be an expandable dictionary. */ + +void +dict_add_pending (struct dictionary *dict, const struct pending *symbol_list) +{ + const struct pending *list; + int i; + + for (list = symbol_list; list != NULL; list = list->next) + { + for (i = 0; i < list->nsyms; ++i) + dict_add_symbol (dict, list->symbol[i]); + } +} + /* Initialize ITERATOR to point at the first symbol in DICT, and return that first symbol, or NULL if DICT is empty. */ @@ -519,35 +519,20 @@ dict_iterator_next (struct dict_iterator *iterator) ->iterator_next (iterator); } -struct symbol * -dict_iter_name_first (const struct dictionary *dict, - const char *name, - struct dict_iterator *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, symbol_compare_ftype *compare, + const lookup_name_info &name, struct dict_iterator *iterator) { - return (DICT_VECTOR (dict))->iter_match_first (dict, name, - compare, iterator); + return (DICT_VECTOR (dict))->iter_match_first (dict, name, iterator); } struct symbol * -dict_iter_match_next (const char *name, symbol_compare_ftype *compare, +dict_iter_match_next (const lookup_name_info &name, struct dict_iterator *iterator) { return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) - ->iter_match_next (name, compare, iterator); + ->iter_match_next (name, iterator); } int @@ -638,11 +623,15 @@ iterator_hashed_advance (struct dict_iterator *iterator) } static struct symbol * -iter_match_first_hashed (const struct dictionary *dict, const char *name, - symbol_compare_ftype *compare, +iter_match_first_hashed (const struct dictionary *dict, + const lookup_name_info &name, struct dict_iterator *iterator) { - unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict); + const language_defn *lang = DICT_LANGUAGE (dict); + unsigned int hash_index = (name.search_name_hash (lang->la_language) + % DICT_HASHED_NBUCKETS (dict)); + symbol_name_matcher_ftype *matches_name + = get_symbol_name_matcher (lang, name); struct symbol *sym; DICT_ITERATOR_DICT (iterator) = dict; @@ -656,11 +645,8 @@ iter_match_first_hashed (const struct dictionary *dict, const char *name, sym = sym->hash_next) { /* Warning: the order of arguments to compare matters! */ - if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) - { - break; - } - + if (matches_name (SYMBOL_SEARCH_NAME (sym), name, NULL)) + break; } DICT_ITERATOR_CURRENT (iterator) = sym; @@ -668,16 +654,19 @@ iter_match_first_hashed (const struct dictionary *dict, const char *name, } static struct symbol * -iter_match_next_hashed (const char *name, symbol_compare_ftype *compare, +iter_match_next_hashed (const lookup_name_info &name, struct dict_iterator *iterator) { + const language_defn *lang = DICT_LANGUAGE (DICT_ITERATOR_DICT (iterator)); + symbol_name_matcher_ftype *matches_name + = get_symbol_name_matcher (lang, name); struct symbol *next; for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next; next != NULL; next = next->hash_next) { - if (compare (SYMBOL_SEARCH_NAME (next), name) == 0) + if (matches_name (SYMBOL_SEARCH_NAME (next), name, NULL)) break; } @@ -693,10 +682,15 @@ insert_symbol_hashed (struct dictionary *dict, struct symbol *sym) { unsigned int hash_index; + unsigned int hash; struct symbol **buckets = DICT_HASHED_BUCKETS (dict); - hash_index = - dict_hash (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict); + /* We don't want to insert a symbol into a dictionary of a different + language. The two may not use the same hashing algorithm. */ + gdb_assert (SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language); + + hash = search_name_hash (SYMBOL_LANGUAGE (sym), SYMBOL_SEARCH_NAME (sym)); + hash_index = hash % DICT_HASHED_NBUCKETS (dict); sym->hash_next = buckets[hash_index]; buckets[hash_index] = sym; } @@ -740,9 +734,8 @@ expand_hashtable (struct dictionary *dict) { int old_nbuckets = DICT_HASHED_NBUCKETS (dict); struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict); - int new_nbuckets = 2*old_nbuckets + 1; - struct symbol **new_buckets = xcalloc (new_nbuckets, - sizeof (struct symbol *)); + int new_nbuckets = 2 * old_nbuckets + 1; + struct symbol **new_buckets = XCNEWVEC (struct symbol *, new_nbuckets); int i; DICT_HASHED_NBUCKETS (dict) = new_nbuckets; @@ -770,13 +763,10 @@ 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. */ +/* See dictionary.h. */ -static unsigned int -dict_hash (const char *string0) +unsigned int +default_search_name_hash (const char *string0) { /* The Ada-encoded version of a name P1.P2...Pn has either the form P1__P2__...Pn or _ada_P1__P2__...Pn (where the Pi @@ -792,7 +782,7 @@ dict_hash (const char *string0) string = string0; if (*string == '_') { - if (strncmp (string, "_ada_", 5) == 0) + if (startswith (string, "_ada_")) string += 5; else return msymbol_hash_iw (string0); @@ -822,14 +812,25 @@ dict_hash (const char *string0) return hash; hash = 0; string += 2; - break; + continue; } - /* FALL THROUGH */ - default: - hash = hash * 67 + *string - 113; - string += 1; + break; + case 'T': + /* Ignore "TKB" suffixes. + + These are used by Ada for subprograms implementing a task body. + For instance for a task T inside package Pck, the name of the + subprogram implementing T's body is `pck__tTKB'. We need to + ignore the "TKB" suffix because searches for this task body + subprogram are going to be performed using `pck__t' (the encoded + version of the natural name `pck.t'). */ + if (strcmp (string, "TKB") == 0) + return hash; break; } + + hash = SYMBOL_HASH_NEXT (hash, *string); + string += 1; } return hash; } @@ -858,27 +859,32 @@ iterator_next_linear (struct dict_iterator *iterator) static struct symbol * iter_match_first_linear (const struct dictionary *dict, - const char *name, symbol_compare_ftype *compare, + const lookup_name_info &name, struct dict_iterator *iterator) { DICT_ITERATOR_DICT (iterator) = dict; DICT_ITERATOR_INDEX (iterator) = -1; - return iter_match_next_linear (name, compare, iterator); + return iter_match_next_linear (name, iterator); } static struct symbol * -iter_match_next_linear (const char *name, symbol_compare_ftype *compare, +iter_match_next_linear (const lookup_name_info &name, struct dict_iterator *iterator) { const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); + const language_defn *lang = DICT_LANGUAGE (dict); + symbol_name_matcher_ftype *matches_name + = get_symbol_name_matcher (lang, name); + int i, nsyms = DICT_LINEAR_NSYMS (dict); struct symbol *sym, *retval = NULL; for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i) { sym = DICT_LINEAR_SYM (dict, i); - if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) + + if (matches_name (SYMBOL_SEARCH_NAME (sym), name, NULL)) { retval = sym; break; @@ -917,9 +923,8 @@ add_symbol_linear_expandable (struct dictionary *dict, { DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2; DICT_LINEAR_SYMS (dict) - = xrealloc (DICT_LINEAR_SYMS (dict), - DICT_LINEAR_EXPANDABLE_CAPACITY (dict) - * sizeof (struct symbol *)); + = XRESIZEVEC (struct symbol *, DICT_LINEAR_SYMS (dict), + DICT_LINEAR_EXPANDABLE_CAPACITY (dict)); } DICT_LINEAR_SYM (dict, nsyms - 1) = sym;