1 /* Routines for name->symbol lookups in GDB. 2 3 Copyright (C) 2003-2015 Free Software Foundation, Inc. 4 5 Contributed by David Carlton <carlton@bactrian.org> and by Kealia, 6 Inc. 7 8 This file is part of GDB. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 23 #include "defs.h" 24 #include <ctype.h> 25 #include "gdb_obstack.h" 26 #include "symtab.h" 27 #include "buildsym.h" 28 #include "dictionary.h" 29 30 /* This file implements dictionaries, which are tables that associate 31 symbols to names. They are represented by an opaque type 'struct 32 dictionary'. That type has various internal implementations, which 33 you can choose between depending on what properties you need 34 (e.g. fast lookup, order-preserving, expandable). 35 36 Each dictionary starts with a 'virtual function table' that 37 contains the functions that actually implement the various 38 operations that dictionaries provide. (Note, however, that, for 39 the sake of client code, we also provide some functions that can be 40 implemented generically in terms of the functions in the vtable.) 41 42 To add a new dictionary implementation <impl>, what you should do 43 is: 44 45 * Add a new element DICT_<IMPL> to dict_type. 46 47 * Create a new structure dictionary_<impl>. If your new 48 implementation is a variant of an existing one, make sure that 49 their structs have the same initial data members. Define accessor 50 macros for your new data members. 51 52 * Implement all the functions in dict_vector as static functions, 53 whose name is the same as the corresponding member of dict_vector 54 plus _<impl>. You don't have to do this for those members where 55 you can reuse existing generic functions 56 (e.g. add_symbol_nonexpandable, free_obstack) or in the case where 57 your new implementation is a variant of an existing implementation 58 and where the variant doesn't affect the member function in 59 question. 60 61 * Define a static const struct dict_vector dict_<impl>_vector. 62 63 * Define a function dict_create_<impl> to create these 64 gizmos. Add its declaration to dictionary.h. 65 66 To add a new operation <op> on all existing implementations, what 67 you should do is: 68 69 * Add a new member <op> to struct dict_vector. 70 71 * If there is useful generic behavior <op>, define a static 72 function <op>_something_informative that implements that behavior. 73 (E.g. add_symbol_nonexpandable, free_obstack.) 74 75 * For every implementation <impl> that should have its own specific 76 behavior for <op>, define a static function <op>_<impl> 77 implementing it. 78 79 * Modify all existing dict_vector_<impl>'s to include the appropriate 80 member. 81 82 * Define a function dict_<op> that looks up <op> in the dict_vector 83 and calls the appropriate function. Add a declaration for 84 dict_<op> to dictionary.h. */ 85 86 /* An enum representing the various implementations of dictionaries. 87 Used only for debugging. */ 88 89 enum dict_type 90 { 91 /* Symbols are stored in a fixed-size hash table. */ 92 DICT_HASHED, 93 /* Symbols are stored in an expandable hash table. */ 94 DICT_HASHED_EXPANDABLE, 95 /* Symbols are stored in a fixed-size array. */ 96 DICT_LINEAR, 97 /* Symbols are stored in an expandable array. */ 98 DICT_LINEAR_EXPANDABLE 99 }; 100 101 /* The virtual function table. */ 102 103 struct dict_vector 104 { 105 /* The type of the dictionary. This is only here to make debugging 106 a bit easier; it's not actually used. */ 107 enum dict_type type; 108 /* The function to free a dictionary. */ 109 void (*free) (struct dictionary *dict); 110 /* Add a symbol to a dictionary, if possible. */ 111 void (*add_symbol) (struct dictionary *dict, struct symbol *sym); 112 /* Iterator functions. */ 113 struct symbol *(*iterator_first) (const struct dictionary *dict, 114 struct dict_iterator *iterator); 115 struct symbol *(*iterator_next) (struct dict_iterator *iterator); 116 /* Functions to iterate over symbols with a given name. */ 117 struct symbol *(*iter_match_first) (const struct dictionary *dict, 118 const char *name, 119 symbol_compare_ftype *equiv, 120 struct dict_iterator *iterator); 121 struct symbol *(*iter_match_next) (const char *name, 122 symbol_compare_ftype *equiv, 123 struct dict_iterator *iterator); 124 /* A size function, for maint print symtabs. */ 125 int (*size) (const struct dictionary *dict); 126 }; 127 128 /* Now comes the structs used to store the data for different 129 implementations. If two implementations have data in common, put 130 the common data at the top of their structs, ordered in the same 131 way. */ 132 133 struct dictionary_hashed 134 { 135 int nbuckets; 136 struct symbol **buckets; 137 }; 138 139 struct dictionary_hashed_expandable 140 { 141 /* How many buckets we currently have. */ 142 int nbuckets; 143 struct symbol **buckets; 144 /* How many syms we currently have; we need this so we will know 145 when to add more buckets. */ 146 int nsyms; 147 }; 148 149 struct dictionary_linear 150 { 151 int nsyms; 152 struct symbol **syms; 153 }; 154 155 struct dictionary_linear_expandable 156 { 157 /* How many symbols we currently have. */ 158 int nsyms; 159 struct symbol **syms; 160 /* How many symbols we can store before needing to reallocate. */ 161 int capacity; 162 }; 163 164 /* And now, the star of our show. */ 165 166 struct dictionary 167 { 168 const struct dict_vector *vector; 169 union 170 { 171 struct dictionary_hashed hashed; 172 struct dictionary_hashed_expandable hashed_expandable; 173 struct dictionary_linear linear; 174 struct dictionary_linear_expandable linear_expandable; 175 } 176 data; 177 }; 178 179 /* Accessor macros. */ 180 181 #define DICT_VECTOR(d) (d)->vector 182 183 /* These can be used for DICT_HASHED_EXPANDABLE, too. */ 184 185 #define DICT_HASHED_NBUCKETS(d) (d)->data.hashed.nbuckets 186 #define DICT_HASHED_BUCKETS(d) (d)->data.hashed.buckets 187 #define DICT_HASHED_BUCKET(d,i) DICT_HASHED_BUCKETS (d) [i] 188 189 #define DICT_HASHED_EXPANDABLE_NSYMS(d) (d)->data.hashed_expandable.nsyms 190 191 /* These can be used for DICT_LINEAR_EXPANDABLEs, too. */ 192 193 #define DICT_LINEAR_NSYMS(d) (d)->data.linear.nsyms 194 #define DICT_LINEAR_SYMS(d) (d)->data.linear.syms 195 #define DICT_LINEAR_SYM(d,i) DICT_LINEAR_SYMS (d) [i] 196 197 #define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \ 198 (d)->data.linear_expandable.capacity 199 200 /* The initial size of a DICT_*_EXPANDABLE dictionary. */ 201 202 #define DICT_EXPANDABLE_INITIAL_CAPACITY 10 203 204 /* This calculates the number of buckets we'll use in a hashtable, 205 given the number of symbols that it will contain. */ 206 207 #define DICT_HASHTABLE_SIZE(n) ((n)/5 + 1) 208 209 /* Accessor macros for dict_iterators; they're here rather than 210 dictionary.h because code elsewhere should treat dict_iterators as 211 opaque. */ 212 213 /* The dictionary that the iterator is associated to. */ 214 #define DICT_ITERATOR_DICT(iter) (iter)->dict 215 /* For linear dictionaries, the index of the last symbol returned; for 216 hashed dictionaries, the bucket of the last symbol returned. */ 217 #define DICT_ITERATOR_INDEX(iter) (iter)->index 218 /* For hashed dictionaries, this points to the last symbol returned; 219 otherwise, this is unused. */ 220 #define DICT_ITERATOR_CURRENT(iter) (iter)->current 221 222 /* Declarations of functions for vectors. */ 223 224 /* Functions that might work across a range of dictionary types. */ 225 226 static void add_symbol_nonexpandable (struct dictionary *dict, 227 struct symbol *sym); 228 229 static void free_obstack (struct dictionary *dict); 230 231 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE 232 dictionaries. */ 233 234 static struct symbol *iterator_first_hashed (const struct dictionary *dict, 235 struct dict_iterator *iterator); 236 237 static struct symbol *iterator_next_hashed (struct dict_iterator *iterator); 238 239 static struct symbol *iter_match_first_hashed (const struct dictionary *dict, 240 const char *name, 241 symbol_compare_ftype *compare, 242 struct dict_iterator *iterator); 243 244 static struct symbol *iter_match_next_hashed (const char *name, 245 symbol_compare_ftype *compare, 246 struct dict_iterator *iterator); 247 248 static unsigned int dict_hash (const char *string); 249 250 /* Functions only for DICT_HASHED. */ 251 252 static int size_hashed (const struct dictionary *dict); 253 254 /* Functions only for DICT_HASHED_EXPANDABLE. */ 255 256 static void free_hashed_expandable (struct dictionary *dict); 257 258 static void add_symbol_hashed_expandable (struct dictionary *dict, 259 struct symbol *sym); 260 261 static int size_hashed_expandable (const struct dictionary *dict); 262 263 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE 264 dictionaries. */ 265 266 static struct symbol *iterator_first_linear (const struct dictionary *dict, 267 struct dict_iterator *iterator); 268 269 static struct symbol *iterator_next_linear (struct dict_iterator *iterator); 270 271 static struct symbol *iter_match_first_linear (const struct dictionary *dict, 272 const char *name, 273 symbol_compare_ftype *compare, 274 struct dict_iterator *iterator); 275 276 static struct symbol *iter_match_next_linear (const char *name, 277 symbol_compare_ftype *compare, 278 struct dict_iterator *iterator); 279 280 static int size_linear (const struct dictionary *dict); 281 282 /* Functions only for DICT_LINEAR_EXPANDABLE. */ 283 284 static void free_linear_expandable (struct dictionary *dict); 285 286 static void add_symbol_linear_expandable (struct dictionary *dict, 287 struct symbol *sym); 288 289 /* Various vectors that we'll actually use. */ 290 291 static const struct dict_vector dict_hashed_vector = 292 { 293 DICT_HASHED, /* type */ 294 free_obstack, /* free */ 295 add_symbol_nonexpandable, /* add_symbol */ 296 iterator_first_hashed, /* iterator_first */ 297 iterator_next_hashed, /* iterator_next */ 298 iter_match_first_hashed, /* iter_name_first */ 299 iter_match_next_hashed, /* iter_name_next */ 300 size_hashed, /* size */ 301 }; 302 303 static const struct dict_vector dict_hashed_expandable_vector = 304 { 305 DICT_HASHED_EXPANDABLE, /* type */ 306 free_hashed_expandable, /* free */ 307 add_symbol_hashed_expandable, /* add_symbol */ 308 iterator_first_hashed, /* iterator_first */ 309 iterator_next_hashed, /* iterator_next */ 310 iter_match_first_hashed, /* iter_name_first */ 311 iter_match_next_hashed, /* iter_name_next */ 312 size_hashed_expandable, /* size */ 313 }; 314 315 static const struct dict_vector dict_linear_vector = 316 { 317 DICT_LINEAR, /* type */ 318 free_obstack, /* free */ 319 add_symbol_nonexpandable, /* add_symbol */ 320 iterator_first_linear, /* iterator_first */ 321 iterator_next_linear, /* iterator_next */ 322 iter_match_first_linear, /* iter_name_first */ 323 iter_match_next_linear, /* iter_name_next */ 324 size_linear, /* size */ 325 }; 326 327 static const struct dict_vector dict_linear_expandable_vector = 328 { 329 DICT_LINEAR_EXPANDABLE, /* type */ 330 free_linear_expandable, /* free */ 331 add_symbol_linear_expandable, /* add_symbol */ 332 iterator_first_linear, /* iterator_first */ 333 iterator_next_linear, /* iterator_next */ 334 iter_match_first_linear, /* iter_name_first */ 335 iter_match_next_linear, /* iter_name_next */ 336 size_linear, /* size */ 337 }; 338 339 /* Declarations of helper functions (i.e. ones that don't go into 340 vectors). */ 341 342 static struct symbol *iterator_hashed_advance (struct dict_iterator *iter); 343 344 static void insert_symbol_hashed (struct dictionary *dict, 345 struct symbol *sym); 346 347 static void expand_hashtable (struct dictionary *dict); 348 349 /* The creation functions. */ 350 351 /* Create a dictionary implemented via a fixed-size hashtable. All 352 memory it uses is allocated on OBSTACK; the environment is 353 initialized from SYMBOL_LIST. */ 354 355 struct dictionary * 356 dict_create_hashed (struct obstack *obstack, 357 const struct pending *symbol_list) 358 { 359 struct dictionary *retval; 360 int nsyms = 0, nbuckets, i; 361 struct symbol **buckets; 362 const struct pending *list_counter; 363 364 retval = obstack_alloc (obstack, sizeof (struct dictionary)); 365 DICT_VECTOR (retval) = &dict_hashed_vector; 366 367 /* Calculate the number of symbols, and allocate space for them. */ 368 for (list_counter = symbol_list; 369 list_counter != NULL; 370 list_counter = list_counter->next) 371 { 372 nsyms += list_counter->nsyms; 373 } 374 nbuckets = DICT_HASHTABLE_SIZE (nsyms); 375 DICT_HASHED_NBUCKETS (retval) = nbuckets; 376 buckets = obstack_alloc (obstack, nbuckets * sizeof (struct symbol *)); 377 memset (buckets, 0, nbuckets * sizeof (struct symbol *)); 378 DICT_HASHED_BUCKETS (retval) = buckets; 379 380 /* Now fill the buckets. */ 381 for (list_counter = symbol_list; 382 list_counter != NULL; 383 list_counter = list_counter->next) 384 { 385 for (i = list_counter->nsyms - 1; i >= 0; --i) 386 { 387 insert_symbol_hashed (retval, list_counter->symbol[i]); 388 } 389 } 390 391 return retval; 392 } 393 394 /* Create a dictionary implemented via a hashtable that grows as 395 necessary. The dictionary is initially empty; to add symbols to 396 it, call dict_add_symbol(). Call dict_free() when you're done with 397 it. */ 398 399 extern struct dictionary * 400 dict_create_hashed_expandable (void) 401 { 402 struct dictionary *retval; 403 404 retval = xmalloc (sizeof (struct dictionary)); 405 DICT_VECTOR (retval) = &dict_hashed_expandable_vector; 406 DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY; 407 DICT_HASHED_BUCKETS (retval) = xcalloc (DICT_EXPANDABLE_INITIAL_CAPACITY, 408 sizeof (struct symbol *)); 409 DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0; 410 411 return retval; 412 } 413 414 /* Create a dictionary implemented via a fixed-size array. All memory 415 it uses is allocated on OBSTACK; the environment is initialized 416 from the SYMBOL_LIST. The symbols are ordered in the same order 417 that they're found in SYMBOL_LIST. */ 418 419 struct dictionary * 420 dict_create_linear (struct obstack *obstack, 421 const struct pending *symbol_list) 422 { 423 struct dictionary *retval; 424 int nsyms = 0, i, j; 425 struct symbol **syms; 426 const struct pending *list_counter; 427 428 retval = obstack_alloc (obstack, sizeof (struct dictionary)); 429 DICT_VECTOR (retval) = &dict_linear_vector; 430 431 /* Calculate the number of symbols, and allocate space for them. */ 432 for (list_counter = symbol_list; 433 list_counter != NULL; 434 list_counter = list_counter->next) 435 { 436 nsyms += list_counter->nsyms; 437 } 438 DICT_LINEAR_NSYMS (retval) = nsyms; 439 syms = obstack_alloc (obstack, nsyms * sizeof (struct symbol *)); 440 DICT_LINEAR_SYMS (retval) = syms; 441 442 /* Now fill in the symbols. Start filling in from the back, so as 443 to preserve the original order of the symbols. */ 444 for (list_counter = symbol_list, j = nsyms - 1; 445 list_counter != NULL; 446 list_counter = list_counter->next) 447 { 448 for (i = list_counter->nsyms - 1; 449 i >= 0; 450 --i, --j) 451 { 452 syms[j] = list_counter->symbol[i]; 453 } 454 } 455 456 return retval; 457 } 458 459 /* Create a dictionary implemented via an array that grows as 460 necessary. The dictionary is initially empty; to add symbols to 461 it, call dict_add_symbol(). Call dict_free() when you're done with 462 it. */ 463 464 struct dictionary * 465 dict_create_linear_expandable (void) 466 { 467 struct dictionary *retval; 468 469 retval = xmalloc (sizeof (struct dictionary)); 470 DICT_VECTOR (retval) = &dict_linear_expandable_vector; 471 DICT_LINEAR_NSYMS (retval) = 0; 472 DICT_LINEAR_EXPANDABLE_CAPACITY (retval) 473 = DICT_EXPANDABLE_INITIAL_CAPACITY; 474 DICT_LINEAR_SYMS (retval) 475 = xmalloc (DICT_LINEAR_EXPANDABLE_CAPACITY (retval) 476 * sizeof (struct symbol *)); 477 478 return retval; 479 } 480 481 /* The functions providing the dictionary interface. */ 482 483 /* Free the memory used by a dictionary that's not on an obstack. (If 484 any.) */ 485 486 void 487 dict_free (struct dictionary *dict) 488 { 489 (DICT_VECTOR (dict))->free (dict); 490 } 491 492 /* Add SYM to DICT. DICT had better be expandable. */ 493 494 void 495 dict_add_symbol (struct dictionary *dict, struct symbol *sym) 496 { 497 (DICT_VECTOR (dict))->add_symbol (dict, sym); 498 } 499 500 /* Utility to add a list of symbols to a dictionary. 501 DICT must be an expandable dictionary. */ 502 503 void 504 dict_add_pending (struct dictionary *dict, const struct pending *symbol_list) 505 { 506 const struct pending *list; 507 int i; 508 509 for (list = symbol_list; list != NULL; list = list->next) 510 { 511 for (i = 0; i < list->nsyms; ++i) 512 dict_add_symbol (dict, list->symbol[i]); 513 } 514 } 515 516 /* Initialize ITERATOR to point at the first symbol in DICT, and 517 return that first symbol, or NULL if DICT is empty. */ 518 519 struct symbol * 520 dict_iterator_first (const struct dictionary *dict, 521 struct dict_iterator *iterator) 522 { 523 return (DICT_VECTOR (dict))->iterator_first (dict, iterator); 524 } 525 526 /* Advance ITERATOR, and return the next symbol, or NULL if there are 527 no more symbols. */ 528 529 struct symbol * 530 dict_iterator_next (struct dict_iterator *iterator) 531 { 532 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) 533 ->iterator_next (iterator); 534 } 535 536 struct symbol * 537 dict_iter_name_first (const struct dictionary *dict, 538 const char *name, 539 struct dict_iterator *iterator) 540 { 541 return dict_iter_match_first (dict, name, strcmp_iw, iterator); 542 } 543 544 struct symbol * 545 dict_iter_name_next (const char *name, struct dict_iterator *iterator) 546 { 547 return dict_iter_match_next (name, strcmp_iw, iterator); 548 } 549 550 struct symbol * 551 dict_iter_match_first (const struct dictionary *dict, 552 const char *name, symbol_compare_ftype *compare, 553 struct dict_iterator *iterator) 554 { 555 return (DICT_VECTOR (dict))->iter_match_first (dict, name, 556 compare, iterator); 557 } 558 559 struct symbol * 560 dict_iter_match_next (const char *name, symbol_compare_ftype *compare, 561 struct dict_iterator *iterator) 562 { 563 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator))) 564 ->iter_match_next (name, compare, iterator); 565 } 566 567 int 568 dict_size (const struct dictionary *dict) 569 { 570 return (DICT_VECTOR (dict))->size (dict); 571 } 572 573 /* Now come functions (well, one function, currently) that are 574 implemented generically by means of the vtable. Typically, they're 575 rarely used. */ 576 577 /* Test to see if DICT is empty. */ 578 579 int 580 dict_empty (struct dictionary *dict) 581 { 582 struct dict_iterator iter; 583 584 return (dict_iterator_first (dict, &iter) == NULL); 585 } 586 587 588 /* The functions implementing the dictionary interface. */ 589 590 /* Generic functions, where appropriate. */ 591 592 static void 593 free_obstack (struct dictionary *dict) 594 { 595 /* Do nothing! */ 596 } 597 598 static void 599 add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym) 600 { 601 internal_error (__FILE__, __LINE__, 602 _("dict_add_symbol: non-expandable dictionary")); 603 } 604 605 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE. */ 606 607 static struct symbol * 608 iterator_first_hashed (const struct dictionary *dict, 609 struct dict_iterator *iterator) 610 { 611 DICT_ITERATOR_DICT (iterator) = dict; 612 DICT_ITERATOR_INDEX (iterator) = -1; 613 return iterator_hashed_advance (iterator); 614 } 615 616 static struct symbol * 617 iterator_next_hashed (struct dict_iterator *iterator) 618 { 619 struct symbol *next; 620 621 next = DICT_ITERATOR_CURRENT (iterator)->hash_next; 622 623 if (next == NULL) 624 return iterator_hashed_advance (iterator); 625 else 626 { 627 DICT_ITERATOR_CURRENT (iterator) = next; 628 return next; 629 } 630 } 631 632 static struct symbol * 633 iterator_hashed_advance (struct dict_iterator *iterator) 634 { 635 const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); 636 int nbuckets = DICT_HASHED_NBUCKETS (dict); 637 int i; 638 639 for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nbuckets; ++i) 640 { 641 struct symbol *sym = DICT_HASHED_BUCKET (dict, i); 642 643 if (sym != NULL) 644 { 645 DICT_ITERATOR_INDEX (iterator) = i; 646 DICT_ITERATOR_CURRENT (iterator) = sym; 647 return sym; 648 } 649 } 650 651 return NULL; 652 } 653 654 static struct symbol * 655 iter_match_first_hashed (const struct dictionary *dict, const char *name, 656 symbol_compare_ftype *compare, 657 struct dict_iterator *iterator) 658 { 659 unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict); 660 struct symbol *sym; 661 662 DICT_ITERATOR_DICT (iterator) = dict; 663 664 /* Loop through the symbols in the given bucket, breaking when SYM 665 first matches. If SYM never matches, it will be set to NULL; 666 either way, we have the right return value. */ 667 668 for (sym = DICT_HASHED_BUCKET (dict, hash_index); 669 sym != NULL; 670 sym = sym->hash_next) 671 { 672 /* Warning: the order of arguments to compare matters! */ 673 if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) 674 { 675 break; 676 } 677 678 } 679 680 DICT_ITERATOR_CURRENT (iterator) = sym; 681 return sym; 682 } 683 684 static struct symbol * 685 iter_match_next_hashed (const char *name, symbol_compare_ftype *compare, 686 struct dict_iterator *iterator) 687 { 688 struct symbol *next; 689 690 for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next; 691 next != NULL; 692 next = next->hash_next) 693 { 694 if (compare (SYMBOL_SEARCH_NAME (next), name) == 0) 695 break; 696 } 697 698 DICT_ITERATOR_CURRENT (iterator) = next; 699 700 return next; 701 } 702 703 /* Insert SYM into DICT. */ 704 705 static void 706 insert_symbol_hashed (struct dictionary *dict, 707 struct symbol *sym) 708 { 709 unsigned int hash_index; 710 struct symbol **buckets = DICT_HASHED_BUCKETS (dict); 711 712 hash_index = 713 dict_hash (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict); 714 sym->hash_next = buckets[hash_index]; 715 buckets[hash_index] = sym; 716 } 717 718 static int 719 size_hashed (const struct dictionary *dict) 720 { 721 return DICT_HASHED_NBUCKETS (dict); 722 } 723 724 /* Functions only for DICT_HASHED_EXPANDABLE. */ 725 726 static void 727 free_hashed_expandable (struct dictionary *dict) 728 { 729 xfree (DICT_HASHED_BUCKETS (dict)); 730 xfree (dict); 731 } 732 733 static void 734 add_symbol_hashed_expandable (struct dictionary *dict, 735 struct symbol *sym) 736 { 737 int nsyms = ++DICT_HASHED_EXPANDABLE_NSYMS (dict); 738 739 if (DICT_HASHTABLE_SIZE (nsyms) > DICT_HASHED_NBUCKETS (dict)) 740 expand_hashtable (dict); 741 742 insert_symbol_hashed (dict, sym); 743 DICT_HASHED_EXPANDABLE_NSYMS (dict) = nsyms; 744 } 745 746 static int 747 size_hashed_expandable (const struct dictionary *dict) 748 { 749 return DICT_HASHED_EXPANDABLE_NSYMS (dict); 750 } 751 752 static void 753 expand_hashtable (struct dictionary *dict) 754 { 755 int old_nbuckets = DICT_HASHED_NBUCKETS (dict); 756 struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict); 757 int new_nbuckets = 2*old_nbuckets + 1; 758 struct symbol **new_buckets = xcalloc (new_nbuckets, 759 sizeof (struct symbol *)); 760 int i; 761 762 DICT_HASHED_NBUCKETS (dict) = new_nbuckets; 763 DICT_HASHED_BUCKETS (dict) = new_buckets; 764 765 for (i = 0; i < old_nbuckets; ++i) 766 { 767 struct symbol *sym, *next_sym; 768 769 sym = old_buckets[i]; 770 if (sym != NULL) 771 { 772 for (next_sym = sym->hash_next; 773 next_sym != NULL; 774 next_sym = sym->hash_next) 775 { 776 insert_symbol_hashed (dict, sym); 777 sym = next_sym; 778 } 779 780 insert_symbol_hashed (dict, sym); 781 } 782 } 783 784 xfree (old_buckets); 785 } 786 787 /* Produce an unsigned hash value from STRING0 that is consistent 788 with strcmp_iw, strcmp, and, at least on Ada symbols, wild_match. 789 That is, two identifiers equivalent according to any of those three 790 comparison operators hash to the same value. */ 791 792 static unsigned int 793 dict_hash (const char *string0) 794 { 795 /* The Ada-encoded version of a name P1.P2...Pn has either the form 796 P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi 797 are lower-cased identifiers). The <suffix> (which can be empty) 798 encodes additional information about the denoted entity. This 799 routine hashes such names to msymbol_hash_iw(Pn). It actually 800 does this for a superset of both valid Pi and of <suffix>, but 801 in other cases it simply returns msymbol_hash_iw(STRING0). */ 802 803 const char *string; 804 unsigned int hash; 805 806 string = string0; 807 if (*string == '_') 808 { 809 if (strncmp (string, "_ada_", 5) == 0) 810 string += 5; 811 else 812 return msymbol_hash_iw (string0); 813 } 814 815 hash = 0; 816 while (*string) 817 { 818 /* Ignore "TKB" suffixes. 819 820 These are used by Ada for subprograms implementing a task body. 821 For instance for a task T inside package Pck, the name of the 822 subprogram implementing T's body is `pck__tTKB'. We need to 823 ignore the "TKB" suffix because searches for this task body 824 subprogram are going to be performed using `pck__t' (the encoded 825 version of the natural name `pck.t'). */ 826 if (strcmp (string, "TKB") == 0) 827 return hash; 828 829 switch (*string) 830 { 831 case '$': 832 case '.': 833 case 'X': 834 if (string0 == string) 835 return msymbol_hash_iw (string0); 836 else 837 return hash; 838 case ' ': 839 case '(': 840 return msymbol_hash_iw (string0); 841 case '_': 842 if (string[1] == '_' && string != string0) 843 { 844 int c = string[2]; 845 846 if ((c < 'a' || c > 'z') && c != 'O') 847 return hash; 848 hash = 0; 849 string += 2; 850 break; 851 } 852 /* FALL THROUGH */ 853 default: 854 hash = SYMBOL_HASH_NEXT (hash, *string); 855 string += 1; 856 break; 857 } 858 } 859 return hash; 860 } 861 862 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */ 863 864 static struct symbol * 865 iterator_first_linear (const struct dictionary *dict, 866 struct dict_iterator *iterator) 867 { 868 DICT_ITERATOR_DICT (iterator) = dict; 869 DICT_ITERATOR_INDEX (iterator) = 0; 870 return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL; 871 } 872 873 static struct symbol * 874 iterator_next_linear (struct dict_iterator *iterator) 875 { 876 const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); 877 878 if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict)) 879 return NULL; 880 else 881 return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator)); 882 } 883 884 static struct symbol * 885 iter_match_first_linear (const struct dictionary *dict, 886 const char *name, symbol_compare_ftype *compare, 887 struct dict_iterator *iterator) 888 { 889 DICT_ITERATOR_DICT (iterator) = dict; 890 DICT_ITERATOR_INDEX (iterator) = -1; 891 892 return iter_match_next_linear (name, compare, iterator); 893 } 894 895 static struct symbol * 896 iter_match_next_linear (const char *name, symbol_compare_ftype *compare, 897 struct dict_iterator *iterator) 898 { 899 const struct dictionary *dict = DICT_ITERATOR_DICT (iterator); 900 int i, nsyms = DICT_LINEAR_NSYMS (dict); 901 struct symbol *sym, *retval = NULL; 902 903 for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i) 904 { 905 sym = DICT_LINEAR_SYM (dict, i); 906 if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0) 907 { 908 retval = sym; 909 break; 910 } 911 } 912 913 DICT_ITERATOR_INDEX (iterator) = i; 914 915 return retval; 916 } 917 918 static int 919 size_linear (const struct dictionary *dict) 920 { 921 return DICT_LINEAR_NSYMS (dict); 922 } 923 924 /* Functions only for DICT_LINEAR_EXPANDABLE. */ 925 926 static void 927 free_linear_expandable (struct dictionary *dict) 928 { 929 xfree (DICT_LINEAR_SYMS (dict)); 930 xfree (dict); 931 } 932 933 934 static void 935 add_symbol_linear_expandable (struct dictionary *dict, 936 struct symbol *sym) 937 { 938 int nsyms = ++DICT_LINEAR_NSYMS (dict); 939 940 /* Do we have enough room? If not, grow it. */ 941 if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict)) 942 { 943 DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2; 944 DICT_LINEAR_SYMS (dict) 945 = xrealloc (DICT_LINEAR_SYMS (dict), 946 DICT_LINEAR_EXPANDABLE_CAPACITY (dict) 947 * sizeof (struct symbol *)); 948 } 949 950 DICT_LINEAR_SYM (dict, nsyms - 1) = sym; 951 } 952