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