GDB (API)
|
00001 /* Routines for name->symbol lookups in GDB. 00002 00003 Copyright (C) 2003-2013 Free Software Foundation, Inc. 00004 00005 Contributed by David Carlton <carlton@bactrian.org> and by Kealia, 00006 Inc. 00007 00008 This file is part of GDB. 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation; either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00022 00023 #include "defs.h" 00024 #include <ctype.h> 00025 #include "gdb_obstack.h" 00026 #include "symtab.h" 00027 #include "buildsym.h" 00028 #include "gdb_assert.h" 00029 #include "dictionary.h" 00030 00031 /* This file implements dictionaries, which are tables that associate 00032 symbols to names. They are represented by an opaque type 'struct 00033 dictionary'. That type has various internal implementations, which 00034 you can choose between depending on what properties you need 00035 (e.g. fast lookup, order-preserving, expandable). 00036 00037 Each dictionary starts with a 'virtual function table' that 00038 contains the functions that actually implement the various 00039 operations that dictionaries provide. (Note, however, that, for 00040 the sake of client code, we also provide some functions that can be 00041 implemented generically in terms of the functions in the vtable.) 00042 00043 To add a new dictionary implementation <impl>, what you should do 00044 is: 00045 00046 * Add a new element DICT_<IMPL> to dict_type. 00047 00048 * Create a new structure dictionary_<impl>. If your new 00049 implementation is a variant of an existing one, make sure that 00050 their structs have the same initial data members. Define accessor 00051 macros for your new data members. 00052 00053 * Implement all the functions in dict_vector as static functions, 00054 whose name is the same as the corresponding member of dict_vector 00055 plus _<impl>. You don't have to do this for those members where 00056 you can reuse existing generic functions 00057 (e.g. add_symbol_nonexpandable, free_obstack) or in the case where 00058 your new implementation is a variant of an existing implementation 00059 and where the variant doesn't affect the member function in 00060 question. 00061 00062 * Define a static const struct dict_vector dict_<impl>_vector. 00063 00064 * Define a function dict_create_<impl> to create these 00065 gizmos. Add its declaration to dictionary.h. 00066 00067 To add a new operation <op> on all existing implementations, what 00068 you should do is: 00069 00070 * Add a new member <op> to struct dict_vector. 00071 00072 * If there is useful generic behavior <op>, define a static 00073 function <op>_something_informative that implements that behavior. 00074 (E.g. add_symbol_nonexpandable, free_obstack.) 00075 00076 * For every implementation <impl> that should have its own specific 00077 behavior for <op>, define a static function <op>_<impl> 00078 implementing it. 00079 00080 * Modify all existing dict_vector_<impl>'s to include the appropriate 00081 member. 00082 00083 * Define a function dict_<op> that looks up <op> in the dict_vector 00084 and calls the appropriate function. Add a declaration for 00085 dict_<op> to dictionary.h. */ 00086 00087 /* An enum representing the various implementations of dictionaries. 00088 Used only for debugging. */ 00089 00090 enum dict_type 00091 { 00092 /* Symbols are stored in a fixed-size hash table. */ 00093 DICT_HASHED, 00094 /* Symbols are stored in an expandable hash table. */ 00095 DICT_HASHED_EXPANDABLE, 00096 /* Symbols are stored in a fixed-size array. */ 00097 DICT_LINEAR, 00098 /* Symbols are stored in an expandable array. */ 00099 DICT_LINEAR_EXPANDABLE 00100 }; 00101 00102 /* The virtual function table. */ 00103 00104 struct dict_vector 00105 { 00106 /* The type of the dictionary. This is only here to make debugging 00107 a bit easier; it's not actually used. */ 00108 enum dict_type type; 00109 /* The function to free a dictionary. */ 00110 void (*free) (struct dictionary *dict); 00111 /* Add a symbol to a dictionary, if possible. */ 00112 void (*add_symbol) (struct dictionary *dict, struct symbol *sym); 00113 /* Iterator functions. */ 00114 struct symbol *(*iterator_first) (const struct dictionary *dict, 00115 struct dict_iterator *iterator); 00116 struct symbol *(*iterator_next) (struct dict_iterator *iterator); 00117 /* Functions to iterate over symbols with a given name. */ 00118 struct symbol *(*iter_match_first) (const struct dictionary *dict, 00119 const char *name, 00120 symbol_compare_ftype *equiv, 00121 struct dict_iterator *iterator); 00122 struct symbol *(*iter_match_next) (const char *name, 00123 symbol_compare_ftype *equiv, 00124 struct dict_iterator *iterator); 00125 /* A size function, for maint print symtabs. */ 00126 int (*size) (const struct dictionary *dict); 00127 }; 00128 00129 /* Now comes the structs used to store the data for different 00130 implementations. If two implementations have data in common, put 00131 the common data at the top of their structs, ordered in the same 00132 way. */ 00133 00134 struct dictionary_hashed 00135 { 00136 int nbuckets; 00137 struct symbol **buckets; 00138 }; 00139 00140 struct dictionary_hashed_expandable 00141 { 00142 /* How many buckets we currently have. */ 00143 int nbuckets; 00144 struct symbol **buckets; 00145 /* How many syms we currently have; we need this so we will know 00146 when to add more buckets. */ 00147 int nsyms; 00148 }; 00149 00150 struct dictionary_linear 00151 { 00152 int nsyms; 00153 struct symbol **syms; 00154 }; 00155 00156 struct dictionary_linear_expandable 00157 { 00158 /* How many symbols we currently have. */ 00159 int nsyms; 00160 struct symbol **syms; 00161 /* How many symbols we can store before needing to reallocate. */ 00162 int capacity; 00163 }; 00164 00165 /* And now, the star of our show. */ 00166 00167 struct dictionary 00168 { 00169 const struct dict_vector *vector; 00170 union 00171 { 00172 struct dictionary_hashed hashed; 00173 struct dictionary_hashed_expandable hashed_expandable; 00174 struct dictionary_linear linear; 00175 struct dictionary_linear_expandable linear_expandable; 00176 } 00177 data; 00178 }; 00179 00180 /* Accessor macros. */ 00181 00182 #define DICT_VECTOR(d) (d)->vector 00183 00184 /* These can be used for DICT_HASHED_EXPANDABLE, too. */ 00185 00186 #define DICT_HASHED_NBUCKETS(d) (d)->data.hashed.nbuckets 00187 #define DICT_HASHED_BUCKETS(d) (d)->data.hashed.buckets 00188 #define DICT_HASHED_BUCKET(d,i) DICT_HASHED_BUCKETS (d) [i] 00189 00190 #define DICT_HASHED_EXPANDABLE_NSYMS(d) (d)->data.hashed_expandable.nsyms 00191 00192 /* These can be used for DICT_LINEAR_EXPANDABLEs, too. */ 00193 00194 #define DICT_LINEAR_NSYMS(d) (d)->data.linear.nsyms 00195 #define DICT_LINEAR_SYMS(d) (d)->data.linear.syms 00196 #define DICT_LINEAR_SYM(d,i) DICT_LINEAR_SYMS (d) [i] 00197 00198 #define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \ 00199 (d)->data.linear_expandable.capacity 00200 00201 /* The initial size of a DICT_*_EXPANDABLE dictionary. */ 00202 00203 #define DICT_EXPANDABLE_INITIAL_CAPACITY 10 00204 00205 /* This calculates the number of buckets we'll use in a hashtable, 00206 given the number of symbols that it will contain. */ 00207 00208 #define DICT_HASHTABLE_SIZE(n) ((n)/5 + 1) 00209 00210 /* Accessor macros for dict_iterators; they're here rather than 00211 dictionary.h because code elsewhere should treat dict_iterators as 00212 opaque. */ 00213 00214 /* The dictionary that the iterator is associated to. */ 00215 #define DICT_ITERATOR_DICT(iter) (iter)->dict 00216 /* For linear dictionaries, the index of the last symbol returned; for 00217 hashed dictionaries, the bucket of the last symbol returned. */ 00218 #define DICT_ITERATOR_INDEX(iter) (iter)->index 00219 /* For hashed dictionaries, this points to the last symbol returned; 00220 otherwise, this is unused. */ 00221 #define DICT_ITERATOR_CURRENT(iter) (iter)->current 00222 00223 /* Declarations of functions for vectors. */ 00224 00225 /* Functions that might work across a range of dictionary types. */ 00226 00227 static void add_symbol_nonexpandable (struct dictionary *dict, 00228 struct symbol *sym); 00229 00230 static void free_obstack (struct dictionary *dict); 00231 00232 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE 00233 dictionaries. */ 00234 00235 static struct symbol *iterator_first_hashed (const struct dictionary *dict, 00236 struct dict_iterator *iterator); 00237 00238 static struct symbol *iterator_next_hashed (struct dict_iterator *iterator); 00239 00240 static struct symbol *iter_match_first_hashed (const struct dictionary *dict, 00241 const char *name, 00242 symbol_compare_ftype *compare, 00243 struct dict_iterator *iterator); 00244 00245 static struct symbol *iter_match_next_hashed (const char *name, 00246 symbol_compare_ftype *compare, 00247 struct dict_iterator *iterator); 00248 00249 static unsigned int dict_hash (const char *string); 00250 00251 /* Functions only for DICT_HASHED. */ 00252 00253 static int size_hashed (const struct dictionary *dict); 00254 00255 /* Functions only for DICT_HASHED_EXPANDABLE. */ 00256 00257 static void free_hashed_expandable (struct dictionary *dict); 00258 00259 static void add_symbol_hashed_expandable (struct dictionary *dict, 00260 struct symbol *sym); 00261 00262 static int size_hashed_expandable (const struct dictionary *dict); 00263 00264 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE 00265 dictionaries. */ 00266 00267 static struct symbol *iterator_first_linear (const struct dictionary *dict, 00268 struct dict_iterator *iterator); 00269 00270 static struct symbol *iterator_next_linear (struct dict_iterator *iterator); 00271 00272 static struct symbol *iter_match_first_linear (const struct dictionary *dict, 00273 const char *name, 00274 symbol_compare_ftype *compare, 00275 struct dict_iterator *iterator); 00276 00277 static struct symbol *iter_match_next_linear (const char *name, 00278 symbol_compare_ftype *compare, 00279 struct dict_iterator *iterator); 00280 00281 static int size_linear (const struct dictionary *dict); 00282 00283 /* Functions only for DICT_LINEAR_EXPANDABLE. */ 00284 00285 static void free_linear_expandable (struct dictionary *dict); 00286 00287 static void add_symbol_linear_expandable (struct dictionary *dict, 00288 struct symbol *sym); 00289 00290 /* Various vectors that we'll actually use. */ 00291 00292 static const struct dict_vector dict_hashed_vector = 00293 { 00294 DICT_HASHED, /* type */ 00295 free_obstack, /* free */ 00296 add_symbol_nonexpandable, /* add_symbol */ 00297 iterator_first_hashed, /* iterator_first */ 00298 iterator_next_hashed, /* iterator_next */ 00299 iter_match_first_hashed, /* iter_name_first */ 00300 iter_match_next_hashed, /* iter_name_next */ 00301 size_hashed, /* size */ 00302 }; 00303 00304 static const struct dict_vector dict_hashed_expandable_vector = 00305 { 00306 DICT_HASHED_EXPANDABLE, /* type */ 00307 free_hashed_expandable, /* free */ 00308 add_symbol_hashed_expandable, /* add_symbol */ 00309 iterator_first_hashed, /* iterator_first */ 00310 iterator_next_hashed, /* iterator_next */ 00311 iter_match_first_hashed, /* iter_name_first */ 00312 iter_match_next_hashed, /* iter_name_next */ 00313 size_hashed_expandable, /* size */ 00314 }; 00315 00316 static const struct dict_vector dict_linear_vector = 00317 { 00318 DICT_LINEAR, /* type */ 00319 free_obstack, /* free */ 00320 add_symbol_nonexpandable, /* add_symbol */ 00321 iterator_first_linear, /* iterator_first */ 00322 iterator_next_linear, /* iterator_next */ 00323 iter_match_first_linear, /* iter_name_first */ 00324 iter_match_next_linear, /* iter_name_next */ 00325 size_linear, /* size */ 00326 }; 00327 00328 static const struct dict_vector dict_linear_expandable_vector = 00329 { 00330 DICT_LINEAR_EXPANDABLE, /* type */ 00331 free_linear_expandable, /* free */ 00332 add_symbol_linear_expandable, /* add_symbol */ 00333 iterator_first_linear, /* iterator_first */ 00334 iterator_next_linear, /* iterator_next */ 00335 iter_match_first_linear, /* iter_name_first */ 00336 iter_match_next_linear, /* iter_name_next */ 00337 size_linear, /* size */ 00338 }; 00339 00340 /* Declarations of helper functions (i.e. ones that don't go into 00341 vectors). */ 00342 00343 static struct symbol *iterator_hashed_advance (struct dict_iterator *iter); 00344 00345 static void insert_symbol_hashed (struct dictionary *dict, 00346 struct symbol *sym); 00347 00348 static void expand_hashtable (struct dictionary *dict); 00349 00350 /* The creation functions. */ 00351 00352 /* Create a dictionary implemented via a fixed-size hashtable. All 00353 memory it uses is allocated on OBSTACK; the environment is 00354 initialized from SYMBOL_LIST. */ 00355 00356 struct dictionary * 00357 dict_create_hashed (struct obstack *obstack, 00358 const struct pending *symbol_list) 00359 { 00360 struct dictionary *retval; 00361 int nsyms = 0, nbuckets, i; 00362 struct symbol **buckets; 00363 const struct pending *list_counter; 00364 00365 retval = obstack_alloc (obstack, sizeof (struct dictionary)); 00366 DICT_VECTOR (retval) = &dict_hashed_vector; 00367 00368 /* Calculate the number of symbols, and allocate space for them. */ 00369 for (list_counter = symbol_list; 00370 list_counter != NULL; 00371 list_counter = list_counter->next) 00372 { 00373 nsyms += list_counter->nsyms; 00374 } 00375 nbuckets = DICT_HASHTABLE_SIZE (nsyms); 00376 DICT_HASHED_NBUCKETS (retval) = nbuckets; 00377 buckets = obstack_alloc (obstack, nbuckets * sizeof (struct symbol *)); 00378 memset (buckets, 0, nbuckets * sizeof (struct symbol *)); 00379 DICT_HASHED_BUCKETS (retval) = buckets; 00380 00381 /* Now fill the buckets. */ 00382 for (list_counter = symbol_list; 00383 list_counter != NULL; 00384 list_counter = list_counter->next) 00385 { 00386 for (i = list_counter->nsyms - 1; i >= 0; --i) 00387 { 00388 insert_symbol_hashed (retval, list_counter->symbol[i]); 00389 } 00390 } 00391 00392 return retval; 00393 } 00394 00395 /* Create a dictionary implemented via a hashtable that grows as 00396 necessary. The dictionary is initially empty; to add symbols to 00397 it, call dict_add_symbol(). Call dict_free() when you're done with 00398 it. */ 00399 00400 extern struct dictionary * 00401 dict_create_hashed_expandable (void) 00402 { 00403 struct dictionary *retval; 00404 00405 retval = xmalloc (sizeof (struct dictionary)); 00406 DICT_VECTOR (retval) = &dict_hashed_expandable_vector; 00407 DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY; 00408 DICT_HASHED_BUCKETS (retval) = xcalloc (DICT_EXPANDABLE_INITIAL_CAPACITY, 00409 sizeof (struct symbol *)); 00410 DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0; 00411 00412 return retval; 00413 } 00414 00415 /* Create a dictionary implemented via a fixed-size array. All memory 00416 it uses is allocated on OBSTACK; the environment is initialized 00417 from the SYMBOL_LIST. The symbols are ordered in the same order 00418 that they're found in SYMBOL_LIST. */ 00419 00420 struct dictionary * 00421 dict_create_linear (struct obstack *obstack, 00422 const struct pending *symbol_list) 00423 { 00424 struct dictionary *retval; 00425 int nsyms = 0, i, j; 00426 struct symbol **syms; 00427 const struct pending *list_counter; 00428 00429 retval = obstack_alloc (obstack, sizeof (struct dictionary)); 00430 DICT_VECTOR (retval) = &dict_linear_vector; 00431 00432 /* Calculate the number of symbols, and allocate space for them. */ 00433 for (list_counter = symbol_list; 00434 list_counter != NULL; 00435 list_counter = list_counter->next) 00436 { 00437 nsyms += list_counter->nsyms; 00438 } 00439 DICT_LINEAR_NSYMS (retval) = nsyms; 00440 syms = obstack_alloc (obstack, nsyms * sizeof (struct symbol *)); 00441 DICT_LINEAR_SYMS (retval) = syms; 00442 00443 /* Now fill in the symbols. Start filling in from the back, so as 00444 to preserve the original order of the symbols. */ 00445 for (list_counter = symbol_list, j = nsyms - 1; 00446 list_counter != NULL; 00447 list_counter = list_counter->next) 00448 { 00449 for (i = list_counter->nsyms - 1; 00450 i >= 0; 00451 --i, --j) 00452 { 00453 syms[j] = list_counter->symbol[i]; 00454 } 00455 } 00456 00457 return retval; 00458 } 00459 00460 /* Create a dictionary implemented via an array that grows as 00461 necessary. The dictionary is initially empty; to add symbols to 00462 it, call dict_add_symbol(). Call dict_free() when you're done with 00463 it. */ 00464 00465 struct dictionary * 00466 dict_create_linear_expandable (void) 00467 { 00468 struct dictionary *retval; 00469 00470 retval = xmalloc (sizeof (struct dictionary)); 00471 DICT_VECTOR (retval) = &dict_linear_expandable_vector; 00472 DICT_LINEAR_NSYMS (retval) = 0; 00473 DICT_LINEAR_EXPANDABLE_CAPACITY (retval) 00474 = DICT_EXPANDABLE_INITIAL_CAPACITY; 00475 DICT_LINEAR_SYMS (retval) 00476 = xmalloc (DICT_LINEAR_EXPANDABLE_CAPACITY (retval) 00477 * sizeof (struct symbol *)); 00478 00479 return retval; 00480 } 00481 00482 /* The functions providing the dictionary interface. */ 00483 00484 /* Free the memory used by a dictionary that's not on an obstack. (If 00485 any.) */ 00486 00487 void 00488 dict_free (struct dictionary *dict) 00489 { 00490 (DICT_VECTOR (dict))->free (dict); 00491 } 00492 00493 /* Add SYM to DICT. DICT had better be expandable. */ 00494 00495 void 00496 dict_add_symbol (struct dictionary *dict, struct symbol *sym) 00497 { 00498 (DICT_VECTOR (dict))->add_symbol (dict, sym); 00499 } 00500 00501 /* Utility to add a list of symbols to a dictionary. 00502 DICT must be an expandable dictionary. */ 00503 00504 void 00505 dict_add_pending (struct dictionary *dict, const struct pending *symbol_list) 00506 { 00507 const struct pending *list; 00508 int i; 00509 00510 for (list = symbol_list; list != NULL; list = list->next) 00511 { 00512 for (i = 0; i < list->nsyms; ++i) 00513 dict_add_symbol (dict, list->symbol[i]); 00514 } 00515 } 00516 00517 /* Initialize ITERATOR to point at the first symbol in DICT, and 00518 return that first symbol, or NULL if DICT is empty. */ 00519 00520 struct symbol * 00521 dict_iterator_first (const struct dictionary *dict, 00522 struct dict_iterator *iterator) 00523 { 00524 return (DICT_VECTOR (dict))->iterator_first (dict, iterator); 00525 } 00526 00527 /* Advance ITERATOR, and return the next symbol, or NULL if there are 00528 no more symbols. */ 00529 00530 struct symbol * 00531 dict_iterator_next (struct dict_iterator *iterator) 00532 { 00533 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) 00534 ->iterator_next (iterator); 00535 } 00536 00537 struct symbol * 00538 dict_iter_name_first (const struct dictionary *dict, 00539 const char *name, 00540 struct dict_iterator *iterator) 00541 { 00542 return dict_iter_match_first (dict, name, strcmp_iw, iterator); 00543 } 00544 00545 struct symbol * 00546 dict_iter_name_next (const char *name, struct dict_iterator *iterator) 00547 { 00548 return dict_iter_match_next (name, strcmp_iw, iterator); 00549 } 00550 00551 struct symbol * 00552 dict_iter_match_first (const struct dictionary *dict, 00553 const char *name, symbol_compare_ftype *compare, 00554 struct dict_iterator *iterator) 00555 { 00556 return (DICT_VECTOR (dict))->iter_match_first (dict, name, 00557 compare, iterator); 00558 } 00559 00560 struct symbol * 00561 dict_iter_match_next (const char *name, symbol_compare_ftype *compare, 00562 struct dict_iterator *iterator) 00563 { 00564 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) 00565 ->iter_match_next (name, compare, iterator); 00566 } 00567 00568 int 00569 dict_size (const struct dictionary *dict) 00570 { 00571 return (DICT_VECTOR (dict))->size (dict); 00572 } 00573 00574 /* Now come functions (well, one function, currently) that are 00575 implemented generically by means of the vtable. Typically, they're 00576 rarely used. */ 00577 00578 /* Test to see if DICT is empty. */ 00579 00580 int 00581 dict_empty (struct dictionary *dict) 00582 { 00583 struct dict_iterator iter; 00584 00585 return (dict_iterator_first (dict, &iter) == NULL); 00586 } 00587 00588 00589 /* The functions implementing the dictionary interface. */ 00590 00591 /* Generic functions, where appropriate. */ 00592 00593 static void 00594 free_obstack (struct dictionary *dict) 00595 { 00596 /* Do nothing! */ 00597 } 00598 00599 static void 00600 add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym) 00601 { 00602 internal_error (__FILE__, __LINE__, 00603 _("dict_add_symbol: non-expandable dictionary")); 00604 } 00605 00606 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE. */ 00607 00608 static struct symbol * 00609 iterator_first_hashed (const struct dictionary *dict, 00610 struct dict_iterator *iterator) 00611 { 00612 DICT_ITERATOR_DICT (iterator) = dict; 00613 DICT_ITERATOR_INDEX (iterator) = -1; 00614 return iterator_hashed_advance (iterator); 00615 } 00616 00617 static struct symbol * 00618 iterator_next_hashed (struct dict_iterator *iterator) 00619 { 00620 struct symbol *next; 00621 00622 next = DICT_ITERATOR_CURRENT (iterator)->hash_next; 00623 00624 if (next == NULL) 00625 return iterator_hashed_advance (iterator); 00626 else 00627 { 00628 DICT_ITERATOR_CURRENT (iterator) = next; 00629 return next; 00630 } 00631 } 00632 00633 static struct symbol * 00634 iterator_hashed_advance (struct dict_iterator *iterator) 00635 { 00636 const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); 00637 int nbuckets = DICT_HASHED_NBUCKETS (dict); 00638 int i; 00639 00640 for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nbuckets; ++i) 00641 { 00642 struct symbol *sym = DICT_HASHED_BUCKET (dict, i); 00643 00644 if (sym != NULL) 00645 { 00646 DICT_ITERATOR_INDEX (iterator) = i; 00647 DICT_ITERATOR_CURRENT (iterator) = sym; 00648 return sym; 00649 } 00650 } 00651 00652 return NULL; 00653 } 00654 00655 static struct symbol * 00656 iter_match_first_hashed (const struct dictionary *dict, const char *name, 00657 symbol_compare_ftype *compare, 00658 struct dict_iterator *iterator) 00659 { 00660 unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict); 00661 struct symbol *sym; 00662 00663 DICT_ITERATOR_DICT (iterator) = dict; 00664 00665 /* Loop through the symbols in the given bucket, breaking when SYM 00666 first matches. If SYM never matches, it will be set to NULL; 00667 either way, we have the right return value. */ 00668 00669 for (sym = DICT_HASHED_BUCKET (dict, hash_index); 00670 sym != NULL; 00671 sym = sym->hash_next) 00672 { 00673 /* Warning: the order of arguments to compare matters! */ 00674 if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) 00675 { 00676 break; 00677 } 00678 00679 } 00680 00681 DICT_ITERATOR_CURRENT (iterator) = sym; 00682 return sym; 00683 } 00684 00685 static struct symbol * 00686 iter_match_next_hashed (const char *name, symbol_compare_ftype *compare, 00687 struct dict_iterator *iterator) 00688 { 00689 struct symbol *next; 00690 00691 for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next; 00692 next != NULL; 00693 next = next->hash_next) 00694 { 00695 if (compare (SYMBOL_SEARCH_NAME (next), name) == 0) 00696 break; 00697 } 00698 00699 DICT_ITERATOR_CURRENT (iterator) = next; 00700 00701 return next; 00702 } 00703 00704 /* Insert SYM into DICT. */ 00705 00706 static void 00707 insert_symbol_hashed (struct dictionary *dict, 00708 struct symbol *sym) 00709 { 00710 unsigned int hash_index; 00711 struct symbol **buckets = DICT_HASHED_BUCKETS (dict); 00712 00713 hash_index = 00714 dict_hash (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict); 00715 sym->hash_next = buckets[hash_index]; 00716 buckets[hash_index] = sym; 00717 } 00718 00719 static int 00720 size_hashed (const struct dictionary *dict) 00721 { 00722 return DICT_HASHED_NBUCKETS (dict); 00723 } 00724 00725 /* Functions only for DICT_HASHED_EXPANDABLE. */ 00726 00727 static void 00728 free_hashed_expandable (struct dictionary *dict) 00729 { 00730 xfree (DICT_HASHED_BUCKETS (dict)); 00731 xfree (dict); 00732 } 00733 00734 static void 00735 add_symbol_hashed_expandable (struct dictionary *dict, 00736 struct symbol *sym) 00737 { 00738 int nsyms = ++DICT_HASHED_EXPANDABLE_NSYMS (dict); 00739 00740 if (DICT_HASHTABLE_SIZE (nsyms) > DICT_HASHED_NBUCKETS (dict)) 00741 expand_hashtable (dict); 00742 00743 insert_symbol_hashed (dict, sym); 00744 DICT_HASHED_EXPANDABLE_NSYMS (dict) = nsyms; 00745 } 00746 00747 static int 00748 size_hashed_expandable (const struct dictionary *dict) 00749 { 00750 return DICT_HASHED_EXPANDABLE_NSYMS (dict); 00751 } 00752 00753 static void 00754 expand_hashtable (struct dictionary *dict) 00755 { 00756 int old_nbuckets = DICT_HASHED_NBUCKETS (dict); 00757 struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict); 00758 int new_nbuckets = 2*old_nbuckets + 1; 00759 struct symbol **new_buckets = xcalloc (new_nbuckets, 00760 sizeof (struct symbol *)); 00761 int i; 00762 00763 DICT_HASHED_NBUCKETS (dict) = new_nbuckets; 00764 DICT_HASHED_BUCKETS (dict) = new_buckets; 00765 00766 for (i = 0; i < old_nbuckets; ++i) 00767 { 00768 struct symbol *sym, *next_sym; 00769 00770 sym = old_buckets[i]; 00771 if (sym != NULL) 00772 { 00773 for (next_sym = sym->hash_next; 00774 next_sym != NULL; 00775 next_sym = sym->hash_next) 00776 { 00777 insert_symbol_hashed (dict, sym); 00778 sym = next_sym; 00779 } 00780 00781 insert_symbol_hashed (dict, sym); 00782 } 00783 } 00784 00785 xfree (old_buckets); 00786 } 00787 00788 /* Produce an unsigned hash value from STRING0 that is consistent 00789 with strcmp_iw, strcmp, and, at least on Ada symbols, wild_match. 00790 That is, two identifiers equivalent according to any of those three 00791 comparison operators hash to the same value. */ 00792 00793 static unsigned int 00794 dict_hash (const char *string0) 00795 { 00796 /* The Ada-encoded version of a name P1.P2...Pn has either the form 00797 P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi 00798 are lower-cased identifiers). The <suffix> (which can be empty) 00799 encodes additional information about the denoted entity. This 00800 routine hashes such names to msymbol_hash_iw(Pn). It actually 00801 does this for a superset of both valid Pi and of <suffix>, but 00802 in other cases it simply returns msymbol_hash_iw(STRING0). */ 00803 00804 const char *string; 00805 unsigned int hash; 00806 00807 string = string0; 00808 if (*string == '_') 00809 { 00810 if (strncmp (string, "_ada_", 5) == 0) 00811 string += 5; 00812 else 00813 return msymbol_hash_iw (string0); 00814 } 00815 00816 hash = 0; 00817 while (*string) 00818 { 00819 /* Ignore "TKB" suffixes. 00820 00821 These are used by Ada for subprograms implementing a task body. 00822 For instance for a task T inside package Pck, the name of the 00823 subprogram implementing T's body is `pck__tTKB'. We need to 00824 ignore the "TKB" suffix because searches for this task body 00825 subprogram are going to be performed using `pck__t' (the encoded 00826 version of the natural name `pck.t'). */ 00827 if (strcmp (string, "TKB") == 0) 00828 return hash; 00829 00830 switch (*string) 00831 { 00832 case '$': 00833 case '.': 00834 case 'X': 00835 if (string0 == string) 00836 return msymbol_hash_iw (string0); 00837 else 00838 return hash; 00839 case ' ': 00840 case '(': 00841 return msymbol_hash_iw (string0); 00842 case '_': 00843 if (string[1] == '_' && string != string0) 00844 { 00845 int c = string[2]; 00846 00847 if ((c < 'a' || c > 'z') && c != 'O') 00848 return hash; 00849 hash = 0; 00850 string += 2; 00851 break; 00852 } 00853 /* FALL THROUGH */ 00854 default: 00855 hash = SYMBOL_HASH_NEXT (hash, *string); 00856 string += 1; 00857 break; 00858 } 00859 } 00860 return hash; 00861 } 00862 00863 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */ 00864 00865 static struct symbol * 00866 iterator_first_linear (const struct dictionary *dict, 00867 struct dict_iterator *iterator) 00868 { 00869 DICT_ITERATOR_DICT (iterator) = dict; 00870 DICT_ITERATOR_INDEX (iterator) = 0; 00871 return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL; 00872 } 00873 00874 static struct symbol * 00875 iterator_next_linear (struct dict_iterator *iterator) 00876 { 00877 const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); 00878 00879 if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict)) 00880 return NULL; 00881 else 00882 return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator)); 00883 } 00884 00885 static struct symbol * 00886 iter_match_first_linear (const struct dictionary *dict, 00887 const char *name, symbol_compare_ftype *compare, 00888 struct dict_iterator *iterator) 00889 { 00890 DICT_ITERATOR_DICT (iterator) = dict; 00891 DICT_ITERATOR_INDEX (iterator) = -1; 00892 00893 return iter_match_next_linear (name, compare, iterator); 00894 } 00895 00896 static struct symbol * 00897 iter_match_next_linear (const char *name, symbol_compare_ftype *compare, 00898 struct dict_iterator *iterator) 00899 { 00900 const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); 00901 int i, nsyms = DICT_LINEAR_NSYMS (dict); 00902 struct symbol *sym, *retval = NULL; 00903 00904 for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i) 00905 { 00906 sym = DICT_LINEAR_SYM (dict, i); 00907 if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) 00908 { 00909 retval = sym; 00910 break; 00911 } 00912 } 00913 00914 DICT_ITERATOR_INDEX (iterator) = i; 00915 00916 return retval; 00917 } 00918 00919 static int 00920 size_linear (const struct dictionary *dict) 00921 { 00922 return DICT_LINEAR_NSYMS (dict); 00923 } 00924 00925 /* Functions only for DICT_LINEAR_EXPANDABLE. */ 00926 00927 static void 00928 free_linear_expandable (struct dictionary *dict) 00929 { 00930 xfree (DICT_LINEAR_SYMS (dict)); 00931 xfree (dict); 00932 } 00933 00934 00935 static void 00936 add_symbol_linear_expandable (struct dictionary *dict, 00937 struct symbol *sym) 00938 { 00939 int nsyms = ++DICT_LINEAR_NSYMS (dict); 00940 00941 /* Do we have enough room? If not, grow it. */ 00942 if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict)) 00943 { 00944 DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2; 00945 DICT_LINEAR_SYMS (dict) 00946 = xrealloc (DICT_LINEAR_SYMS (dict), 00947 DICT_LINEAR_EXPANDABLE_CAPACITY (dict) 00948 * sizeof (struct symbol *)); 00949 } 00950 00951 DICT_LINEAR_SYM (dict, nsyms - 1) = sym; 00952 }