]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/dictionary.c
Update year range in copyright notice of all files owned by the GDB project.
[thirdparty/binutils-gdb.git] / gdb / dictionary.c
CommitLineData
de4f826b
DC
1/* Routines for name->symbol lookups in GDB.
2
32d0add0 3 Copyright (C) 2003-2015 Free Software Foundation, Inc.
de4f826b
DC
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
a9762ec7
JB
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
de4f826b 14
a9762ec7
JB
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.
de4f826b
DC
19
20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
de4f826b
DC
22
23#include "defs.h"
c4d840bd 24#include <ctype.h>
de4f826b
DC
25#include "gdb_obstack.h"
26#include "symtab.h"
27#include "buildsym.h"
de4f826b
DC
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
0963b4bd 84 dict_<op> to dictionary.h. */
de4f826b
DC
85
86/* An enum representing the various implementations of dictionaries.
87 Used only for debugging. */
88
89enum 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. */
20605361 98 DICT_LINEAR_EXPANDABLE
de4f826b
DC
99 };
100
101/* The virtual function table. */
102
103struct 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. */
c4d840bd 117 struct symbol *(*iter_match_first) (const struct dictionary *dict,
2edb89d3
JK
118 const char *name,
119 symbol_compare_ftype *equiv,
120 struct dict_iterator *iterator);
c4d840bd 121 struct symbol *(*iter_match_next) (const char *name,
2edb89d3 122 symbol_compare_ftype *equiv,
de4f826b 123 struct dict_iterator *iterator);
de4f826b
DC
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
133struct dictionary_hashed
134{
135 int nbuckets;
136 struct symbol **buckets;
137};
138
139struct 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
149struct dictionary_linear
150{
151 int nsyms;
152 struct symbol **syms;
153};
154
155struct 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
166struct 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
226static void add_symbol_nonexpandable (struct dictionary *dict,
227 struct symbol *sym);
228
229static void free_obstack (struct dictionary *dict);
230
231/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE
232 dictionaries. */
233
234static struct symbol *iterator_first_hashed (const struct dictionary *dict,
235 struct dict_iterator *iterator);
236
237static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
238
c4d840bd
PH
239static struct symbol *iter_match_first_hashed (const struct dictionary *dict,
240 const char *name,
2edb89d3 241 symbol_compare_ftype *compare,
de4f826b
DC
242 struct dict_iterator *iterator);
243
c4d840bd 244static struct symbol *iter_match_next_hashed (const char *name,
2edb89d3 245 symbol_compare_ftype *compare,
c4d840bd
PH
246 struct dict_iterator *iterator);
247
248static unsigned int dict_hash (const char *string);
de4f826b
DC
249
250/* Functions only for DICT_HASHED. */
251
252static int size_hashed (const struct dictionary *dict);
253
254/* Functions only for DICT_HASHED_EXPANDABLE. */
255
256static void free_hashed_expandable (struct dictionary *dict);
257
258static void add_symbol_hashed_expandable (struct dictionary *dict,
259 struct symbol *sym);
260
261static int size_hashed_expandable (const struct dictionary *dict);
262
263/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE
264 dictionaries. */
265
266static struct symbol *iterator_first_linear (const struct dictionary *dict,
267 struct dict_iterator *iterator);
268
269static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
270
c4d840bd
PH
271static struct symbol *iter_match_first_linear (const struct dictionary *dict,
272 const char *name,
2edb89d3 273 symbol_compare_ftype *compare,
c4d840bd 274 struct dict_iterator *iterator);
de4f826b 275
c4d840bd 276static struct symbol *iter_match_next_linear (const char *name,
2edb89d3 277 symbol_compare_ftype *compare,
c4d840bd 278 struct dict_iterator *iterator);
de4f826b
DC
279
280static int size_linear (const struct dictionary *dict);
281
282/* Functions only for DICT_LINEAR_EXPANDABLE. */
283
284static void free_linear_expandable (struct dictionary *dict);
285
286static void add_symbol_linear_expandable (struct dictionary *dict,
287 struct symbol *sym);
288
289/* Various vectors that we'll actually use. */
290
291static const struct dict_vector dict_hashed_vector =
292 {
293 DICT_HASHED, /* type */
294 free_obstack, /* free */
295 add_symbol_nonexpandable, /* add_symbol */
a11a1416 296 iterator_first_hashed, /* iterator_first */
de4f826b 297 iterator_next_hashed, /* iterator_next */
c4d840bd
PH
298 iter_match_first_hashed, /* iter_name_first */
299 iter_match_next_hashed, /* iter_name_next */
de4f826b
DC
300 size_hashed, /* size */
301 };
302
303static 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 */
a11a1416 308 iterator_first_hashed, /* iterator_first */
de4f826b 309 iterator_next_hashed, /* iterator_next */
c4d840bd
PH
310 iter_match_first_hashed, /* iter_name_first */
311 iter_match_next_hashed, /* iter_name_next */
de4f826b
DC
312 size_hashed_expandable, /* size */
313 };
314
315static const struct dict_vector dict_linear_vector =
316 {
317 DICT_LINEAR, /* type */
318 free_obstack, /* free */
319 add_symbol_nonexpandable, /* add_symbol */
a11a1416 320 iterator_first_linear, /* iterator_first */
de4f826b 321 iterator_next_linear, /* iterator_next */
c4d840bd
PH
322 iter_match_first_linear, /* iter_name_first */
323 iter_match_next_linear, /* iter_name_next */
de4f826b
DC
324 size_linear, /* size */
325 };
326
327static 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 */
a11a1416 332 iterator_first_linear, /* iterator_first */
de4f826b 333 iterator_next_linear, /* iterator_next */
c4d840bd
PH
334 iter_match_first_linear, /* iter_name_first */
335 iter_match_next_linear, /* iter_name_next */
de4f826b
DC
336 size_linear, /* size */
337 };
338
339/* Declarations of helper functions (i.e. ones that don't go into
340 vectors). */
341
342static struct symbol *iterator_hashed_advance (struct dict_iterator *iter);
343
344static void insert_symbol_hashed (struct dictionary *dict,
345 struct symbol *sym);
346
347static 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
355struct dictionary *
356dict_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
399extern struct dictionary *
400dict_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
419struct dictionary *
420dict_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
464struct dictionary *
465dict_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
486void
487dict_free (struct dictionary *dict)
488{
489 (DICT_VECTOR (dict))->free (dict);
490}
491
492/* Add SYM to DICT. DICT had better be expandable. */
493
494void
495dict_add_symbol (struct dictionary *dict, struct symbol *sym)
496{
497 (DICT_VECTOR (dict))->add_symbol (dict, sym);
498}
499
0bfa869d
DE
500/* Utility to add a list of symbols to a dictionary.
501 DICT must be an expandable dictionary. */
502
503void
504dict_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
de4f826b
DC
516/* Initialize ITERATOR to point at the first symbol in DICT, and
517 return that first symbol, or NULL if DICT is empty. */
518
519struct symbol *
520dict_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
529struct symbol *
530dict_iterator_next (struct dict_iterator *iterator)
531{
532 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
533 ->iterator_next (iterator);
534}
535
536struct symbol *
537dict_iter_name_first (const struct dictionary *dict,
538 const char *name,
539 struct dict_iterator *iterator)
540{
c4d840bd 541 return dict_iter_match_first (dict, name, strcmp_iw, iterator);
de4f826b
DC
542}
543
544struct symbol *
545dict_iter_name_next (const char *name, struct dict_iterator *iterator)
c4d840bd
PH
546{
547 return dict_iter_match_next (name, strcmp_iw, iterator);
548}
549
550struct symbol *
551dict_iter_match_first (const struct dictionary *dict,
2edb89d3 552 const char *name, symbol_compare_ftype *compare,
c4d840bd
PH
553 struct dict_iterator *iterator)
554{
3e43a32a
MS
555 return (DICT_VECTOR (dict))->iter_match_first (dict, name,
556 compare, iterator);
c4d840bd
PH
557}
558
559struct symbol *
2edb89d3 560dict_iter_match_next (const char *name, symbol_compare_ftype *compare,
c4d840bd 561 struct dict_iterator *iterator)
de4f826b
DC
562{
563 return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
c4d840bd 564 ->iter_match_next (name, compare, iterator);
de4f826b
DC
565}
566
567int
568dict_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
579int
580dict_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
592static void
593free_obstack (struct dictionary *dict)
594{
595 /* Do nothing! */
596}
597
598static void
599add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym)
600{
601 internal_error (__FILE__, __LINE__,
e2e0b3e5 602 _("dict_add_symbol: non-expandable dictionary"));
de4f826b
DC
603}
604
605/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE. */
606
607static struct symbol *
608iterator_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
616static struct symbol *
617iterator_next_hashed (struct dict_iterator *iterator)
618{
de4f826b
DC
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
632static struct symbol *
633iterator_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
654static struct symbol *
2edb89d3
JK
655iter_match_first_hashed (const struct dictionary *dict, const char *name,
656 symbol_compare_ftype *compare,
c4d840bd 657 struct dict_iterator *iterator)
de4f826b 658{
c4d840bd 659 unsigned int hash_index = dict_hash (name) % DICT_HASHED_NBUCKETS (dict);
de4f826b
DC
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 {
c4d840bd
PH
672 /* Warning: the order of arguments to compare matters! */
673 if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0)
de4f826b
DC
674 {
675 break;
676 }
677
678 }
679
680 DICT_ITERATOR_CURRENT (iterator) = sym;
681 return sym;
682}
683
684static struct symbol *
2edb89d3 685iter_match_next_hashed (const char *name, symbol_compare_ftype *compare,
c4d840bd 686 struct dict_iterator *iterator)
de4f826b
DC
687{
688 struct symbol *next;
689
690 for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
691 next != NULL;
692 next = next->hash_next)
693 {
c4d840bd 694 if (compare (SYMBOL_SEARCH_NAME (next), name) == 0)
de4f826b
DC
695 break;
696 }
697
698 DICT_ITERATOR_CURRENT (iterator) = next;
699
700 return next;
701}
702
703/* Insert SYM into DICT. */
704
705static void
706insert_symbol_hashed (struct dictionary *dict,
707 struct symbol *sym)
708{
709 unsigned int hash_index;
710 struct symbol **buckets = DICT_HASHED_BUCKETS (dict);
711
c4d840bd
PH
712 hash_index =
713 dict_hash (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict);
de4f826b
DC
714 sym->hash_next = buckets[hash_index];
715 buckets[hash_index] = sym;
716}
717
718static int
719size_hashed (const struct dictionary *dict)
720{
721 return DICT_HASHED_NBUCKETS (dict);
722}
723
724/* Functions only for DICT_HASHED_EXPANDABLE. */
725
726static void
727free_hashed_expandable (struct dictionary *dict)
728{
729 xfree (DICT_HASHED_BUCKETS (dict));
730 xfree (dict);
731}
732
733static void
734add_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
746static int
747size_hashed_expandable (const struct dictionary *dict)
748{
749 return DICT_HASHED_EXPANDABLE_NSYMS (dict);
750}
751
752static void
753expand_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
6595d32b
MS
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 }
de4f826b 782 }
de4f826b
DC
783
784 xfree (old_buckets);
785}
786
c4d840bd
PH
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
792static unsigned int
1d2a4540 793dict_hash (const char *string0)
c4d840bd
PH
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
1d2a4540 803 const char *string;
c4d840bd 804 unsigned int hash;
c4d840bd 805
1d2a4540
PH
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 }
c4d840bd
PH
814
815 hash = 0;
816 while (*string)
817 {
9ac7f98e
JB
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
c4d840bd
PH
829 switch (*string)
830 {
831 case '$':
832 case '.':
833 case 'X':
1d2a4540
PH
834 if (string0 == string)
835 return msymbol_hash_iw (string0);
836 else
837 return hash;
c4d840bd 838 case ' ':
1d2a4540
PH
839 case '(':
840 return msymbol_hash_iw (string0);
c4d840bd 841 case '_':
1d2a4540 842 if (string[1] == '_' && string != string0)
c4d840bd 843 {
558b1900
JB
844 int c = string[2];
845
846 if ((c < 'a' || c > 'z') && c != 'O')
c4d840bd
PH
847 return hash;
848 hash = 0;
849 string += 2;
850 break;
851 }
852 /* FALL THROUGH */
853 default:
59d7bcaf 854 hash = SYMBOL_HASH_NEXT (hash, *string);
c4d840bd
PH
855 string += 1;
856 break;
857 }
858 }
859 return hash;
860}
861
de4f826b
DC
862/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */
863
864static struct symbol *
865iterator_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
873static struct symbol *
874iterator_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
884static struct symbol *
c4d840bd 885iter_match_first_linear (const struct dictionary *dict,
2edb89d3 886 const char *name, symbol_compare_ftype *compare,
c4d840bd 887 struct dict_iterator *iterator)
de4f826b
DC
888{
889 DICT_ITERATOR_DICT (iterator) = dict;
890 DICT_ITERATOR_INDEX (iterator) = -1;
891
c4d840bd 892 return iter_match_next_linear (name, compare, iterator);
de4f826b
DC
893}
894
895static struct symbol *
2edb89d3 896iter_match_next_linear (const char *name, symbol_compare_ftype *compare,
c4d840bd 897 struct dict_iterator *iterator)
de4f826b
DC
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);
c4d840bd 906 if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0)
de4f826b
DC
907 {
908 retval = sym;
909 break;
910 }
911 }
912
913 DICT_ITERATOR_INDEX (iterator) = i;
914
915 return retval;
916}
917
918static int
919size_linear (const struct dictionary *dict)
920{
921 return DICT_LINEAR_NSYMS (dict);
922}
923
924/* Functions only for DICT_LINEAR_EXPANDABLE. */
925
926static void
927free_linear_expandable (struct dictionary *dict)
928{
929 xfree (DICT_LINEAR_SYMS (dict));
930 xfree (dict);
931}
932
933
934static void
935add_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. */
6595d32b
MS
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 }
de4f826b
DC
949
950 DICT_LINEAR_SYM (dict, nsyms - 1) = sym;
951}