1 /* Routines for name->symbol lookups in GDB.
2 
3    Copyright (C) 2003-2024 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 <ctype.h>
24 #include "gdbsupport/gdb_obstack.h"
25 #include "symtab.h"
26 #include "buildsym.h"
27 #include "dictionary.h"
28 #include "gdbsupport/gdb-safe-ctype.h"
29 #include <unordered_map>
30 #include "language.h"
31 
32 /* This file implements dictionaries, which are tables that associate
33    symbols to names.  They are represented by an opaque type 'struct
34    dictionary'.  That type has various internal implementations, which
35    you can choose between depending on what properties you need
36    (e.g. fast lookup, order-preserving, expandable).
37 
38    Each dictionary starts with a 'virtual function table' that
39    contains the functions that actually implement the various
40    operations that dictionaries provide.  (Note, however, that, for
41    the sake of client code, we also provide some functions that can be
42    implemented generically in terms of the functions in the vtable.)
43 
44    To add a new dictionary implementation <impl>, what you should do
45    is:
46 
47    * Add a new element DICT_<IMPL> to dict_type.
48 
49    * Create a new structure dictionary_<impl>.  If your new
50    implementation is a variant of an existing one, make sure that
51    their structs have the same initial data members.  Define accessor
52    macros for your new data members.
53 
54    * Implement all the functions in dict_vector as static functions,
55    whose name is the same as the corresponding member of dict_vector
56    plus _<impl>.  You don't have to do this for those members where
57    you can reuse existing generic functions
58    (e.g. add_symbol_nonexpandable, free_obstack) or in the case where
59    your new implementation is a variant of an existing implementation
60    and where the variant doesn't affect the member function in
61    question.
62 
63    * Define a static const struct dict_vector dict_<impl>_vector.
64 
65    * Define a function dict_create_<impl> to create these
66    gizmos.  Add its declaration to dictionary.h.
67 
68    To add a new operation <op> on all existing implementations, what
69    you should do is:
70 
71    * Add a new member <op> to struct dict_vector.
72 
73    * If there is useful generic behavior <op>, define a static
74    function <op>_something_informative that implements that behavior.
75    (E.g. add_symbol_nonexpandable, free_obstack.)
76 
77    * For every implementation <impl> that should have its own specific
78    behavior for <op>, define a static function <op>_<impl>
79    implementing it.
80 
81    * Modify all existing dict_vector_<impl>'s to include the appropriate
82    member.
83 
84    * Define a function dict_<op> that looks up <op> in the dict_vector
85    and calls the appropriate function.  Add a declaration for
86    dict_<op> to dictionary.h.  */
87 
88 /* An enum representing the various implementations of dictionaries.
89    Used only for debugging.  */
90 
91 enum dict_type
92   {
93     /* Symbols are stored in a fixed-size hash table.  */
94     DICT_HASHED,
95     /* Symbols are stored in an expandable hash table.  */
96     DICT_HASHED_EXPANDABLE,
97     /* Symbols are stored in a fixed-size array.  */
98     DICT_LINEAR,
99     /* Symbols are stored in an expandable array.  */
100     DICT_LINEAR_EXPANDABLE
101   };
102 
103 /* The virtual function table.  */
104 
105 struct dict_vector
106 {
107   /* The type of the dictionary.  This is only here to make debugging
108      a bit easier; it's not actually used.  */
109   enum dict_type type;
110   /* The function to free a dictionary.  */
111   void (*free) (struct dictionary *dict);
112   /* Add a symbol to a dictionary, if possible.  */
113   void (*add_symbol) (struct dictionary *dict, struct symbol *sym);
114   /* Iterator functions.  */
115   struct symbol *(*iterator_first) (const struct dictionary *dict,
116                                             struct dict_iterator *iterator);
117   struct symbol *(*iterator_next) (struct dict_iterator *iterator);
118   /* Functions to iterate over symbols with a given name.  */
119   struct symbol *(*iter_match_first) (const struct dictionary *dict,
120                                               const lookup_name_info &name,
121                                               struct dict_iterator *iterator);
122   struct symbol *(*iter_match_next) (const lookup_name_info &name,
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 language_defn *language;
169   const struct dict_vector *vector;
170   union
171   {
172     struct dictionary_hashed hashed;
173     struct dictionary_hashed_expandable hashed_expandable;
174     struct dictionary_linear linear;
175     struct dictionary_linear_expandable linear_expandable;
176   }
177   data;
178 };
179 
180 /* Accessor macros.  */
181 
182 #define DICT_VECTOR(d)                            (d)->vector
183 #define DICT_LANGUAGE(d)                (d)->language
184 
185 /* These can be used for DICT_HASHED_EXPANDABLE, too.  */
186 
187 #define DICT_HASHED_NBUCKETS(d)                   (d)->data.hashed.nbuckets
188 #define DICT_HASHED_BUCKETS(d)                    (d)->data.hashed.buckets
189 #define DICT_HASHED_BUCKET(d,i)                   DICT_HASHED_BUCKETS (d) [i]
190 
191 #define DICT_HASHED_EXPANDABLE_NSYMS(d) (d)->data.hashed_expandable.nsyms
192 
193 /* These can be used for DICT_LINEAR_EXPANDABLEs, too.  */
194 
195 #define DICT_LINEAR_NSYMS(d)            (d)->data.linear.nsyms
196 #define DICT_LINEAR_SYMS(d)             (d)->data.linear.syms
197 #define DICT_LINEAR_SYM(d,i)            DICT_LINEAR_SYMS (d) [i]
198 
199 #define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \
200                     (d)->data.linear_expandable.capacity
201 
202 /* The initial size of a DICT_*_EXPANDABLE dictionary.  */
203 
204 #define DICT_EXPANDABLE_INITIAL_CAPACITY 10
205 
206 /* This calculates the number of buckets we'll use in a hashtable,
207    given the number of symbols that it will contain.  */
208 
209 #define DICT_HASHTABLE_SIZE(n)          ((n)/5 + 1)
210 
211 /* Accessor macros for dict_iterators; they're here rather than
212    dictionary.h because code elsewhere should treat dict_iterators as
213    opaque.  */
214 
215 /* The dictionary that the iterator is associated to.  */
216 #define DICT_ITERATOR_DICT(iter)                  (iter)->dict
217 /* For linear dictionaries, the index of the last symbol returned; for
218    hashed dictionaries, the bucket of the last symbol returned.  */
219 #define DICT_ITERATOR_INDEX(iter)                 (iter)->index
220 /* For hashed dictionaries, this points to the last symbol returned;
221    otherwise, this is unused.  */
222 #define DICT_ITERATOR_CURRENT(iter)               (iter)->current
223 
224 /* Declarations of functions for vectors.  */
225 
226 /* Functions that might work across a range of dictionary types.  */
227 
228 static void add_symbol_nonexpandable (struct dictionary *dict,
229                                               struct symbol *sym);
230 
231 static void free_obstack (struct dictionary *dict);
232 
233 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE
234    dictionaries.  */
235 
236 static struct symbol *iterator_first_hashed (const struct dictionary *dict,
237                                                        struct dict_iterator *iterator);
238 
239 static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
240 
241 static struct symbol *iter_match_first_hashed (const struct dictionary *dict,
242                                                          const lookup_name_info &name,
243                                                         struct dict_iterator *iterator);
244 
245 static struct symbol *iter_match_next_hashed (const lookup_name_info &name,
246                                                         struct dict_iterator *iterator);
247 
248 /* Functions only for DICT_HASHED.  */
249 
250 static int size_hashed (const struct dictionary *dict);
251 
252 /* Functions only for DICT_HASHED_EXPANDABLE.  */
253 
254 static void free_hashed_expandable (struct dictionary *dict);
255 
256 static void add_symbol_hashed_expandable (struct dictionary *dict,
257                                                     struct symbol *sym);
258 
259 static int size_hashed_expandable (const struct dictionary *dict);
260 
261 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE
262    dictionaries.  */
263 
264 static struct symbol *iterator_first_linear (const struct dictionary *dict,
265                                                        struct dict_iterator *iterator);
266 
267 static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
268 
269 static struct symbol *iter_match_first_linear (const struct dictionary *dict,
270                                                          const lookup_name_info &name,
271                                                          struct dict_iterator *iterator);
272 
273 static struct symbol *iter_match_next_linear (const lookup_name_info &name,
274                                                         struct dict_iterator *iterator);
275 
276 static int size_linear (const struct dictionary *dict);
277 
278 /* Functions only for DICT_LINEAR_EXPANDABLE.  */
279 
280 static void free_linear_expandable (struct dictionary *dict);
281 
282 static void add_symbol_linear_expandable (struct dictionary *dict,
283                                                     struct symbol *sym);
284 
285 /* Various vectors that we'll actually use.  */
286 
287 static const struct dict_vector dict_hashed_vector =
288   {
289     DICT_HASHED,                        /* type */
290     free_obstack,                       /* free */
291     add_symbol_nonexpandable,           /* add_symbol */
292     iterator_first_hashed,              /* iterator_first */
293     iterator_next_hashed,               /* iterator_next */
294     iter_match_first_hashed,            /* iter_name_first */
295     iter_match_next_hashed,             /* iter_name_next */
296     size_hashed,                        /* size */
297   };
298 
299 static const struct dict_vector dict_hashed_expandable_vector =
300   {
301     DICT_HASHED_EXPANDABLE,             /* type */
302     free_hashed_expandable,             /* free */
303     add_symbol_hashed_expandable,       /* add_symbol */
304     iterator_first_hashed,              /* iterator_first */
305     iterator_next_hashed,               /* iterator_next */
306     iter_match_first_hashed,            /* iter_name_first */
307     iter_match_next_hashed,             /* iter_name_next */
308     size_hashed_expandable,             /* size */
309   };
310 
311 static const struct dict_vector dict_linear_vector =
312   {
313     DICT_LINEAR,                        /* type */
314     free_obstack,                       /* free */
315     add_symbol_nonexpandable,           /* add_symbol */
316     iterator_first_linear,              /* iterator_first */
317     iterator_next_linear,               /* iterator_next */
318     iter_match_first_linear,            /* iter_name_first */
319     iter_match_next_linear,             /* iter_name_next */
320     size_linear,                        /* size */
321   };
322 
323 static const struct dict_vector dict_linear_expandable_vector =
324   {
325     DICT_LINEAR_EXPANDABLE,             /* type */
326     free_linear_expandable,             /* free */
327     add_symbol_linear_expandable,       /* add_symbol */
328     iterator_first_linear,              /* iterator_first */
329     iterator_next_linear,               /* iterator_next */
330     iter_match_first_linear,            /* iter_name_first */
331     iter_match_next_linear,             /* iter_name_next */
332     size_linear,                        /* size */
333   };
334 
335 /* Declarations of helper functions (i.e. ones that don't go into
336    vectors).  */
337 
338 static struct symbol *iterator_hashed_advance (struct dict_iterator *iter);
339 
340 static void insert_symbol_hashed (struct dictionary *dict,
341                                           struct symbol *sym);
342 
343 static void expand_hashtable (struct dictionary *dict);
344 
345 /* The creation functions.  */
346 
347 /* Create a hashed dictionary of a given language.  */
348 
349 static struct dictionary *
dict_create_hashed(struct obstack * obstack,enum language language,const std::vector<symbol * > & symbol_list)350 dict_create_hashed (struct obstack *obstack,
351                         enum language language,
352                         const std::vector<symbol *> &symbol_list)
353 {
354   /* Allocate the dictionary.  */
355   struct dictionary *retval = XOBNEW (obstack, struct dictionary);
356   DICT_VECTOR (retval) = &dict_hashed_vector;
357   DICT_LANGUAGE (retval) = language_def (language);
358 
359   /* Allocate space for symbols.  */
360   int nsyms = symbol_list.size ();
361   int nbuckets = DICT_HASHTABLE_SIZE (nsyms);
362   DICT_HASHED_NBUCKETS (retval) = nbuckets;
363   struct symbol **buckets = XOBNEWVEC (obstack, struct symbol *, nbuckets);
364   memset (buckets, 0, nbuckets * sizeof (struct symbol *));
365   DICT_HASHED_BUCKETS (retval) = buckets;
366 
367   /* Now fill the buckets.  */
368   for (const auto &sym : symbol_list)
369     insert_symbol_hashed (retval, sym);
370 
371   return retval;
372 }
373 
374 /* Create an expandable hashed dictionary of a given language.  */
375 
376 static struct dictionary *
dict_create_hashed_expandable(enum language language)377 dict_create_hashed_expandable (enum language language)
378 {
379   struct dictionary *retval = XNEW (struct dictionary);
380 
381   DICT_VECTOR (retval) = &dict_hashed_expandable_vector;
382   DICT_LANGUAGE (retval) = language_def (language);
383   DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY;
384   DICT_HASHED_BUCKETS (retval) = XCNEWVEC (struct symbol *,
385                                                      DICT_EXPANDABLE_INITIAL_CAPACITY);
386   DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0;
387 
388   return retval;
389 }
390 
391 /* Create a linear dictionary of a given language.  */
392 
393 static struct dictionary *
dict_create_linear(struct obstack * obstack,enum language language,const std::vector<symbol * > & symbol_list)394 dict_create_linear (struct obstack *obstack,
395                         enum language language,
396                         const std::vector<symbol *> &symbol_list)
397 {
398   struct dictionary *retval = XOBNEW (obstack, struct dictionary);
399   DICT_VECTOR (retval) = &dict_linear_vector;
400   DICT_LANGUAGE (retval) = language_def (language);
401 
402   /* Allocate space for symbols.  */
403   int nsyms = symbol_list.size ();
404   DICT_LINEAR_NSYMS (retval) = nsyms;
405   struct symbol **syms = XOBNEWVEC (obstack, struct symbol *, nsyms);
406   DICT_LINEAR_SYMS (retval) = syms;
407 
408   /* Now fill in the symbols.  */
409   int idx = nsyms - 1;
410   for (const auto &sym : symbol_list)
411     syms[idx--] = sym;
412 
413   return retval;
414 }
415 
416 /* Create an expandable linear dictionary of a given language.  */
417 
418 static struct dictionary *
dict_create_linear_expandable(enum language language)419 dict_create_linear_expandable (enum language language)
420 {
421   struct dictionary *retval = XNEW (struct dictionary);
422 
423   DICT_VECTOR (retval) = &dict_linear_expandable_vector;
424   DICT_LANGUAGE (retval) = language_def (language);
425   DICT_LINEAR_NSYMS (retval) = 0;
426   DICT_LINEAR_EXPANDABLE_CAPACITY (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY;
427   DICT_LINEAR_SYMS (retval)
428     = XNEWVEC (struct symbol *, DICT_LINEAR_EXPANDABLE_CAPACITY (retval));
429 
430   return retval;
431 }
432 
433 /* The functions providing the dictionary interface.  */
434 
435 /* Free the memory used by a dictionary that's not on an obstack.  (If
436    any.)  */
437 
438 static void
dict_free(struct dictionary * dict)439 dict_free (struct dictionary *dict)
440 {
441   (DICT_VECTOR (dict))->free (dict);
442 }
443 
444 /* Add SYM to DICT.  DICT had better be expandable.  */
445 
446 static void
dict_add_symbol(struct dictionary * dict,struct symbol * sym)447 dict_add_symbol (struct dictionary *dict, struct symbol *sym)
448 {
449   (DICT_VECTOR (dict))->add_symbol (dict, sym);
450 }
451 
452 /* Utility to add a list of symbols to a dictionary.
453    DICT must be an expandable dictionary.  */
454 
455 static void
dict_add_pending(struct dictionary * dict,const std::vector<symbol * > & symbol_list)456 dict_add_pending (struct dictionary *dict,
457                       const std::vector<symbol *> &symbol_list)
458 {
459   /* Preserve ordering by reversing the list.  */
460   for (auto sym = symbol_list.rbegin (); sym != symbol_list.rend (); ++sym)
461     dict_add_symbol (dict, *sym);
462 }
463 
464 /* Initialize ITERATOR to point at the first symbol in DICT, and
465    return that first symbol, or NULL if DICT is empty.  */
466 
467 static struct symbol *
dict_iterator_first(const struct dictionary * dict,struct dict_iterator * iterator)468 dict_iterator_first (const struct dictionary *dict,
469                          struct dict_iterator *iterator)
470 {
471   return (DICT_VECTOR (dict))->iterator_first (dict, iterator);
472 }
473 
474 /* Advance ITERATOR, and return the next symbol, or NULL if there are
475    no more symbols.  */
476 
477 static struct symbol *
dict_iterator_next(struct dict_iterator * iterator)478 dict_iterator_next (struct dict_iterator *iterator)
479 {
480   return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
481     ->iterator_next (iterator);
482 }
483 
484 static struct symbol *
dict_iter_match_first(const struct dictionary * dict,const lookup_name_info & name,struct dict_iterator * iterator)485 dict_iter_match_first (const struct dictionary *dict,
486                            const lookup_name_info &name,
487                            struct dict_iterator *iterator)
488 {
489   return (DICT_VECTOR (dict))->iter_match_first (dict, name, iterator);
490 }
491 
492 static struct symbol *
dict_iter_match_next(const lookup_name_info & name,struct dict_iterator * iterator)493 dict_iter_match_next (const lookup_name_info &name,
494                           struct dict_iterator *iterator)
495 {
496   return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
497     ->iter_match_next (name, iterator);
498 }
499 
500 static int
dict_size(const struct dictionary * dict)501 dict_size (const struct dictionary *dict)
502 {
503   return (DICT_VECTOR (dict))->size (dict);
504 }
505 
506 /* Now come functions (well, one function, currently) that are
507    implemented generically by means of the vtable.  Typically, they're
508    rarely used.  */
509 
510 
511 /* The functions implementing the dictionary interface.  */
512 
513 /* Generic functions, where appropriate.  */
514 
515 static void
free_obstack(struct dictionary * dict)516 free_obstack (struct dictionary *dict)
517 {
518   /* Do nothing!  */
519 }
520 
521 static void
add_symbol_nonexpandable(struct dictionary * dict,struct symbol * sym)522 add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym)
523 {
524   internal_error (_("dict_add_symbol: non-expandable dictionary"));
525 }
526 
527 /* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE.  */
528 
529 static struct symbol *
iterator_first_hashed(const struct dictionary * dict,struct dict_iterator * iterator)530 iterator_first_hashed (const struct dictionary *dict,
531                            struct dict_iterator *iterator)
532 {
533   DICT_ITERATOR_DICT (iterator) = dict;
534   DICT_ITERATOR_INDEX (iterator) = -1;
535   return iterator_hashed_advance (iterator);
536 }
537 
538 static struct symbol *
iterator_next_hashed(struct dict_iterator * iterator)539 iterator_next_hashed (struct dict_iterator *iterator)
540 {
541   struct symbol *next;
542 
543   next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
544 
545   if (next == NULL)
546     return iterator_hashed_advance (iterator);
547   else
548     {
549       DICT_ITERATOR_CURRENT (iterator) = next;
550       return next;
551     }
552 }
553 
554 static struct symbol *
iterator_hashed_advance(struct dict_iterator * iterator)555 iterator_hashed_advance (struct dict_iterator *iterator)
556 {
557   const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
558   int nbuckets = DICT_HASHED_NBUCKETS (dict);
559   int i;
560 
561   for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nbuckets; ++i)
562     {
563       struct symbol *sym = DICT_HASHED_BUCKET (dict, i);
564 
565       if (sym != NULL)
566           {
567             DICT_ITERATOR_INDEX (iterator) = i;
568             DICT_ITERATOR_CURRENT (iterator) = sym;
569             return sym;
570           }
571     }
572 
573   return NULL;
574 }
575 
576 static struct symbol *
iter_match_first_hashed(const struct dictionary * dict,const lookup_name_info & name,struct dict_iterator * iterator)577 iter_match_first_hashed (const struct dictionary *dict,
578                                const lookup_name_info &name,
579                                struct dict_iterator *iterator)
580 {
581   const language_defn *lang = DICT_LANGUAGE (dict);
582   unsigned int hash_index = (name.search_name_hash (lang->la_language)
583                                    % DICT_HASHED_NBUCKETS (dict));
584   symbol_name_matcher_ftype *matches_name
585     = lang->get_symbol_name_matcher (name);
586   struct symbol *sym;
587 
588   DICT_ITERATOR_DICT (iterator) = dict;
589 
590   /* Loop through the symbols in the given bucket, breaking when SYM
591      first matches.  If SYM never matches, it will be set to NULL;
592      either way, we have the right return value.  */
593 
594   for (sym = DICT_HASHED_BUCKET (dict, hash_index);
595        sym != NULL;
596        sym = sym->hash_next)
597     {
598       /* Warning: the order of arguments to compare matters!  */
599       if (matches_name (sym->search_name (), name, NULL))
600           break;
601     }
602 
603   DICT_ITERATOR_CURRENT (iterator) = sym;
604   return sym;
605 }
606 
607 static struct symbol *
iter_match_next_hashed(const lookup_name_info & name,struct dict_iterator * iterator)608 iter_match_next_hashed (const lookup_name_info &name,
609                               struct dict_iterator *iterator)
610 {
611   const language_defn *lang = DICT_LANGUAGE (DICT_ITERATOR_DICT (iterator));
612   symbol_name_matcher_ftype *matches_name
613     = lang->get_symbol_name_matcher (name);
614   struct symbol *next;
615 
616   for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
617        next != NULL;
618        next = next->hash_next)
619     {
620       if (matches_name (next->search_name (), name, NULL))
621           break;
622     }
623 
624   DICT_ITERATOR_CURRENT (iterator) = next;
625 
626   return next;
627 }
628 
629 /* Insert SYM into DICT.  */
630 
631 static void
insert_symbol_hashed(struct dictionary * dict,struct symbol * sym)632 insert_symbol_hashed (struct dictionary *dict,
633                           struct symbol *sym)
634 {
635   unsigned int hash_index;
636   unsigned int hash;
637   struct symbol **buckets = DICT_HASHED_BUCKETS (dict);
638 
639   /* We don't want to insert a symbol into a dictionary of a different
640      language.  The two may not use the same hashing algorithm.  */
641   gdb_assert (sym->language () == DICT_LANGUAGE (dict)->la_language);
642 
643   hash = search_name_hash (sym->language (), sym->search_name ());
644   hash_index = hash % DICT_HASHED_NBUCKETS (dict);
645   sym->hash_next = buckets[hash_index];
646   buckets[hash_index] = sym;
647 }
648 
649 static int
size_hashed(const struct dictionary * dict)650 size_hashed (const struct dictionary *dict)
651 {
652   int nbuckets = DICT_HASHED_NBUCKETS (dict);
653   int total = 0;
654 
655   for (int i = 0; i < nbuckets; ++i)
656     {
657       for (struct symbol *sym = DICT_HASHED_BUCKET (dict, i);
658              sym != nullptr;
659              sym = sym->hash_next)
660           total++;
661     }
662 
663   return total;
664 }
665 
666 /* Functions only for DICT_HASHED_EXPANDABLE.  */
667 
668 static void
free_hashed_expandable(struct dictionary * dict)669 free_hashed_expandable (struct dictionary *dict)
670 {
671   xfree (DICT_HASHED_BUCKETS (dict));
672   xfree (dict);
673 }
674 
675 static void
add_symbol_hashed_expandable(struct dictionary * dict,struct symbol * sym)676 add_symbol_hashed_expandable (struct dictionary *dict,
677                                     struct symbol *sym)
678 {
679   int nsyms = ++DICT_HASHED_EXPANDABLE_NSYMS (dict);
680 
681   if (DICT_HASHTABLE_SIZE (nsyms) > DICT_HASHED_NBUCKETS (dict))
682     expand_hashtable (dict);
683 
684   insert_symbol_hashed (dict, sym);
685   DICT_HASHED_EXPANDABLE_NSYMS (dict) = nsyms;
686 }
687 
688 static int
size_hashed_expandable(const struct dictionary * dict)689 size_hashed_expandable (const struct dictionary *dict)
690 {
691   return DICT_HASHED_EXPANDABLE_NSYMS (dict);
692 }
693 
694 static void
expand_hashtable(struct dictionary * dict)695 expand_hashtable (struct dictionary *dict)
696 {
697   int old_nbuckets = DICT_HASHED_NBUCKETS (dict);
698   struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict);
699   int new_nbuckets = 2 * old_nbuckets + 1;
700   struct symbol **new_buckets = XCNEWVEC (struct symbol *, new_nbuckets);
701   int i;
702 
703   DICT_HASHED_NBUCKETS (dict) = new_nbuckets;
704   DICT_HASHED_BUCKETS (dict) = new_buckets;
705 
706   for (i = 0; i < old_nbuckets; ++i)
707     {
708       struct symbol *sym, *next_sym;
709 
710       sym = old_buckets[i];
711       if (sym != NULL)
712           {
713             for (next_sym = sym->hash_next;
714                  next_sym != NULL;
715                  next_sym = sym->hash_next)
716               {
717                 insert_symbol_hashed (dict, sym);
718                 sym = next_sym;
719               }
720 
721             insert_symbol_hashed (dict, sym);
722           }
723     }
724 
725   xfree (old_buckets);
726 }
727 
728 /* See dictionary.h.  */
729 
730 unsigned int
search_name_hash(const char * string0)731 language_defn::search_name_hash (const char *string0) const
732 {
733   /* The Ada-encoded version of a name P1.P2...Pn has either the form
734      P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi
735      are lower-cased identifiers).  The <suffix> (which can be empty)
736      encodes additional information about the denoted entity.  This
737      routine hashes such names to msymbol_hash_iw(Pn).  It actually
738      does this for a superset of both valid Pi and of <suffix>, but
739      in other cases it simply returns msymbol_hash_iw(STRING0).  */
740 
741   const char *string;
742   unsigned int hash;
743 
744   string = string0;
745   if (*string == '_')
746     {
747       if (startswith (string, "_ada_"))
748           string += 5;
749       else
750           return msymbol_hash_iw (string0);
751     }
752 
753   hash = 0;
754   while (*string)
755     {
756       switch (*string)
757           {
758           case '$':
759           case '.':
760           case 'X':
761             if (string0 == string)
762               return msymbol_hash_iw (string0);
763             else
764               return hash;
765           case ' ':
766           case '(':
767             return msymbol_hash_iw (string0);
768           case '_':
769             if (string[1] == '_' && string != string0)
770               {
771                 int c = string[2];
772 
773                 if (c == 'B' && string[3] == '_')
774                     {
775                       for (string += 4; ISDIGIT (*string); ++string)
776                         ;
777                       continue;
778                     }
779 
780                 if ((c < 'a' || c > 'z') && c != 'O')
781                     return hash;
782                 hash = 0;
783                 string += 2;
784                 continue;
785               }
786             break;
787           case 'T':
788             /* Ignore "TKB" suffixes.
789 
790                These are used by Ada for subprograms implementing a task body.
791                For instance for a task T inside package Pck, the name of the
792                subprogram implementing T's body is `pck__tTKB'.  We need to
793                ignore the "TKB" suffix because searches for this task body
794                subprogram are going to be performed using `pck__t' (the encoded
795                version of the natural name `pck.t').  */
796             if (strcmp (string, "TKB") == 0)
797               return hash;
798             break;
799           }
800 
801       hash = SYMBOL_HASH_NEXT (hash, *string);
802       string += 1;
803     }
804   return hash;
805 }
806 
807 /* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE.  */
808 
809 static struct symbol *
iterator_first_linear(const struct dictionary * dict,struct dict_iterator * iterator)810 iterator_first_linear (const struct dictionary *dict,
811                            struct dict_iterator *iterator)
812 {
813   DICT_ITERATOR_DICT (iterator) = dict;
814   DICT_ITERATOR_INDEX (iterator) = 0;
815   return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL;
816 }
817 
818 static struct symbol *
iterator_next_linear(struct dict_iterator * iterator)819 iterator_next_linear (struct dict_iterator *iterator)
820 {
821   const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
822 
823   if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict))
824     return NULL;
825   else
826     return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator));
827 }
828 
829 static struct symbol *
iter_match_first_linear(const struct dictionary * dict,const lookup_name_info & name,struct dict_iterator * iterator)830 iter_match_first_linear (const struct dictionary *dict,
831                                const lookup_name_info &name,
832                                struct dict_iterator *iterator)
833 {
834   DICT_ITERATOR_DICT (iterator) = dict;
835   DICT_ITERATOR_INDEX (iterator) = -1;
836 
837   return iter_match_next_linear (name, iterator);
838 }
839 
840 static struct symbol *
iter_match_next_linear(const lookup_name_info & name,struct dict_iterator * iterator)841 iter_match_next_linear (const lookup_name_info &name,
842                               struct dict_iterator *iterator)
843 {
844   const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
845   const language_defn *lang = DICT_LANGUAGE (dict);
846   symbol_name_matcher_ftype *matches_name
847     = lang->get_symbol_name_matcher (name);
848 
849   int i, nsyms = DICT_LINEAR_NSYMS (dict);
850   struct symbol *sym, *retval = NULL;
851 
852   for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i)
853     {
854       sym = DICT_LINEAR_SYM (dict, i);
855 
856       if (matches_name (sym->search_name (), name, NULL))
857           {
858             retval = sym;
859             break;
860           }
861     }
862 
863   DICT_ITERATOR_INDEX (iterator) = i;
864 
865   return retval;
866 }
867 
868 static int
size_linear(const struct dictionary * dict)869 size_linear (const struct dictionary *dict)
870 {
871   return DICT_LINEAR_NSYMS (dict);
872 }
873 
874 /* Functions only for DICT_LINEAR_EXPANDABLE.  */
875 
876 static void
free_linear_expandable(struct dictionary * dict)877 free_linear_expandable (struct dictionary *dict)
878 {
879   xfree (DICT_LINEAR_SYMS (dict));
880   xfree (dict);
881 }
882 
883 
884 static void
add_symbol_linear_expandable(struct dictionary * dict,struct symbol * sym)885 add_symbol_linear_expandable (struct dictionary *dict,
886                                     struct symbol *sym)
887 {
888   int nsyms = ++DICT_LINEAR_NSYMS (dict);
889 
890   /* Do we have enough room?  If not, grow it.  */
891   if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict))
892     {
893       DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2;
894       DICT_LINEAR_SYMS (dict)
895           = XRESIZEVEC (struct symbol *, DICT_LINEAR_SYMS (dict),
896                           DICT_LINEAR_EXPANDABLE_CAPACITY (dict));
897     }
898 
899   DICT_LINEAR_SYM (dict, nsyms - 1) = sym;
900 }
901 
902 /* Multi-language dictionary support.  */
903 
904 /* The structure describing a multi-language dictionary.  */
905 
906 struct multidictionary
907 {
908   /* An array of dictionaries, one per language.  All dictionaries
909      must be of the same type.  This should be free'd for expandable
910      dictionary types.  */
911   struct dictionary **dictionaries;
912 
913   /* The number of language dictionaries currently allocated.
914      Only used for expandable dictionaries.  */
915   unsigned short n_allocated_dictionaries;
916 };
917 
918 /* A hasher for enum language.  Injecting this into std is a convenience
919    when using unordered_map with C++11.  */
920 
921 namespace std
922 {
923   template<> struct hash<enum language>
924   {
925     typedef enum language argument_type;
926     typedef std::size_t result_type;
927 
928     result_type operator() (const argument_type &l) const noexcept
929     {
930       return static_cast<result_type> (l);
931     }
932   };
933 } /* namespace std */
934 
935 /* A helper function to collate symbols on the pending list by language.  */
936 
937 static std::unordered_map<enum language, std::vector<symbol *>>
938 collate_pending_symbols_by_language (const struct pending *symbol_list)
939 {
940   std::unordered_map<enum language, std::vector<symbol *>> nsyms;
941 
942   for (const pending *list_counter = symbol_list;
943        list_counter != nullptr; list_counter = list_counter->next)
944     {
945       for (int i = list_counter->nsyms - 1; i >= 0; --i)
946           {
947             enum language language = list_counter->symbol[i]->language ();
948             nsyms[language].push_back (list_counter->symbol[i]);
949           }
950     }
951 
952   return nsyms;
953 }
954 
955 /* See dictionary.h.  */
956 
957 struct multidictionary *
958 mdict_create_hashed (struct obstack *obstack,
959                          const struct pending *symbol_list)
960 {
961   struct multidictionary *retval
962     = XOBNEW (obstack, struct multidictionary);
963   std::unordered_map<enum language, std::vector<symbol *>> nsyms
964     = collate_pending_symbols_by_language (symbol_list);
965 
966   /* Loop over all languages and create/populate dictionaries.  */
967   retval->dictionaries
968     = XOBNEWVEC (obstack, struct dictionary *, nsyms.size ());
969   retval->n_allocated_dictionaries = nsyms.size ();
970 
971   int idx = 0;
972   for (const auto &pair : nsyms)
973     {
974       enum language language = pair.first;
975       std::vector<symbol *> symlist = pair.second;
976 
977       retval->dictionaries[idx++]
978           = dict_create_hashed (obstack, language, symlist);
979     }
980 
981   return retval;
982 }
983 
984 /* See dictionary.h.  */
985 
986 struct multidictionary *
987 mdict_create_hashed_expandable (enum language language)
988 {
989   struct multidictionary *retval = XNEW (struct multidictionary);
990 
991   /* We have no symbol list to populate, but we create an empty
992      dictionary of the requested language to populate later.  */
993   retval->n_allocated_dictionaries = 1;
994   retval->dictionaries = XNEW (struct dictionary *);
995   retval->dictionaries[0] = dict_create_hashed_expandable (language);
996 
997   return retval;
998 }
999 
1000 /* See dictionary.h.  */
1001 
1002 struct multidictionary *
1003 mdict_create_linear (struct obstack *obstack,
1004                          const struct pending *symbol_list)
1005 {
1006   struct multidictionary *retval
1007     = XOBNEW (obstack, struct multidictionary);
1008   std::unordered_map<enum language, std::vector<symbol *>> nsyms
1009     = collate_pending_symbols_by_language (symbol_list);
1010 
1011   /* Loop over all languages and create/populate dictionaries.  */
1012   retval->dictionaries
1013     = XOBNEWVEC (obstack, struct dictionary *, nsyms.size ());
1014   retval->n_allocated_dictionaries = nsyms.size ();
1015 
1016   int idx = 0;
1017   for (const auto &pair : nsyms)
1018     {
1019       enum language language = pair.first;
1020       std::vector<symbol *> symlist = pair.second;
1021 
1022       retval->dictionaries[idx++]
1023           = dict_create_linear (obstack, language, symlist);
1024     }
1025 
1026   return retval;
1027 }
1028 
1029 /* See dictionary.h.  */
1030 
1031 struct multidictionary *
1032 mdict_create_linear_expandable (enum language language)
1033 {
1034   struct multidictionary *retval = XNEW (struct multidictionary);
1035 
1036   /* We have no symbol list to populate, but we create an empty
1037      dictionary to populate later.  */
1038   retval->n_allocated_dictionaries = 1;
1039   retval->dictionaries = XNEW (struct dictionary *);
1040   retval->dictionaries[0] = dict_create_linear_expandable (language);
1041 
1042   return retval;
1043 }
1044 
1045 /* See dictionary.h.  */
1046 
1047 void
1048 mdict_free (struct multidictionary *mdict)
1049 {
1050   /* Grab the type of dictionary being used.  */
1051   enum dict_type type = mdict->dictionaries[0]->vector->type;
1052 
1053   /* Loop over all dictionaries and free them.  */
1054   for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx)
1055     dict_free (mdict->dictionaries[idx]);
1056 
1057   /* Free the dictionary list, if needed.  */
1058   switch (type)
1059     {
1060     case DICT_HASHED:
1061     case DICT_LINEAR:
1062       /* Memory was allocated on an obstack when created.  */
1063       break;
1064 
1065     case DICT_HASHED_EXPANDABLE:
1066     case DICT_LINEAR_EXPANDABLE:
1067       xfree (mdict->dictionaries);
1068       break;
1069     }
1070 }
1071 
1072 /* Helper function to find the dictionary associated with LANGUAGE
1073    or NULL if there is no dictionary of that language.  */
1074 
1075 static struct dictionary *
1076 find_language_dictionary (const struct multidictionary *mdict,
1077                                 enum language language)
1078 {
1079   for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx)
1080     {
1081       if (DICT_LANGUAGE (mdict->dictionaries[idx])->la_language == language)
1082           return mdict->dictionaries[idx];
1083     }
1084 
1085   return nullptr;
1086 }
1087 
1088 /* Create a new language dictionary for LANGUAGE and add it to the
1089    multidictionary MDICT's list of dictionaries.  If MDICT is not
1090    based on expandable dictionaries, this function throws an
1091    internal error.  */
1092 
1093 static struct dictionary *
1094 create_new_language_dictionary (struct multidictionary *mdict,
1095                                         enum language language)
1096 {
1097   struct dictionary *retval = nullptr;
1098 
1099   /* We use the first dictionary entry to decide what create function
1100      to call.  Not optimal but sufficient.  */
1101   gdb_assert (mdict->dictionaries[0] != nullptr);
1102   switch (mdict->dictionaries[0]->vector->type)
1103     {
1104     case DICT_HASHED:
1105     case DICT_LINEAR:
1106       internal_error (_("create_new_language_dictionary: attempted to expand "
1107                               "non-expandable multidictionary"));
1108 
1109     case DICT_HASHED_EXPANDABLE:
1110       retval = dict_create_hashed_expandable (language);
1111       break;
1112 
1113     case DICT_LINEAR_EXPANDABLE:
1114       retval = dict_create_linear_expandable (language);
1115       break;
1116     }
1117 
1118   /* Grow the dictionary vector and save the new dictionary.  */
1119   mdict->dictionaries
1120     = (struct dictionary **) xrealloc (mdict->dictionaries,
1121                                                (++mdict->n_allocated_dictionaries
1122                                                   * sizeof (struct dictionary *)));
1123   mdict->dictionaries[mdict->n_allocated_dictionaries - 1] = retval;
1124 
1125   return retval;
1126 }
1127 
1128 /* See dictionary.h.  */
1129 
1130 void
1131 mdict_add_symbol (struct multidictionary *mdict, struct symbol *sym)
1132 {
1133   struct dictionary *dict
1134     = find_language_dictionary (mdict, sym->language ());
1135 
1136   if (dict == nullptr)
1137     {
1138       /* SYM is of a new language that we haven't previously seen.
1139            Create a new dictionary for it.  */
1140       dict = create_new_language_dictionary (mdict, sym->language ());
1141     }
1142 
1143   dict_add_symbol (dict, sym);
1144 }
1145 
1146 /* See dictionary.h.  */
1147 
1148 void
1149 mdict_add_pending (struct multidictionary *mdict,
1150                        const struct pending *symbol_list)
1151 {
1152   std::unordered_map<enum language, std::vector<symbol *>> nsyms
1153     = collate_pending_symbols_by_language (symbol_list);
1154 
1155   for (const auto &pair : nsyms)
1156     {
1157       enum language language = pair.first;
1158       std::vector<symbol *> symlist = pair.second;
1159       struct dictionary *dict = find_language_dictionary (mdict, language);
1160 
1161       if (dict == nullptr)
1162           {
1163             /* The language was not previously seen.  Create a new dictionary
1164                for it.  */
1165             dict = create_new_language_dictionary (mdict, language);
1166           }
1167 
1168       dict_add_pending (dict, symlist);
1169     }
1170 }
1171 
1172 /* See dictionary.h.  */
1173 
1174 struct symbol *
1175 mdict_iterator_first (const multidictionary *mdict,
1176                           struct mdict_iterator *miterator)
1177 {
1178   miterator->mdict = mdict;
1179   miterator->current_idx = 0;
1180 
1181   for (unsigned short idx = miterator->current_idx;
1182        idx < mdict->n_allocated_dictionaries; ++idx)
1183     {
1184       struct symbol *result
1185           = dict_iterator_first (mdict->dictionaries[idx], &miterator->iterator);
1186 
1187       if (result != nullptr)
1188           {
1189             miterator->current_idx = idx;
1190             return result;
1191           }
1192     }
1193 
1194   return nullptr;
1195 }
1196 
1197 /* See dictionary.h.  */
1198 
1199 struct symbol *
1200 mdict_iterator_next (struct mdict_iterator *miterator)
1201 {
1202   struct symbol *result = dict_iterator_next (&miterator->iterator);
1203 
1204   if (result != nullptr)
1205     return result;
1206 
1207   /* The current dictionary had no matches -- move to the next
1208      dictionary, if any.  */
1209   for (unsigned short idx = ++miterator->current_idx;
1210        idx < miterator->mdict->n_allocated_dictionaries; ++idx)
1211     {
1212       result
1213           = dict_iterator_first (miterator->mdict->dictionaries[idx],
1214                                      &miterator->iterator);
1215       if (result != nullptr)
1216           {
1217             miterator->current_idx = idx;
1218             return result;
1219           }
1220     }
1221 
1222   return nullptr;
1223 }
1224 
1225 /* See dictionary.h.  */
1226 
1227 struct symbol *
1228 mdict_iter_match_first (const struct multidictionary *mdict,
1229                               const lookup_name_info &name,
1230                               struct mdict_iterator *miterator)
1231 {
1232   miterator->mdict = mdict;
1233   miterator->current_idx = 0;
1234 
1235   for (unsigned short idx = miterator->current_idx;
1236        idx < mdict->n_allocated_dictionaries; ++idx)
1237     {
1238       struct symbol *result
1239           = dict_iter_match_first (mdict->dictionaries[idx], name,
1240                                          &miterator->iterator);
1241 
1242       if (result != nullptr)
1243           return result;
1244     }
1245 
1246   return nullptr;
1247 }
1248 
1249 /* See dictionary.h.  */
1250 
1251 struct symbol *
1252 mdict_iter_match_next (const lookup_name_info &name,
1253                            struct mdict_iterator *miterator)
1254 {
1255   /* Search the current dictionary.  */
1256   struct symbol *result = dict_iter_match_next (name, &miterator->iterator);
1257 
1258   if (result != nullptr)
1259     return result;
1260 
1261   /* The current dictionary had no matches -- move to the next
1262      dictionary, if any.  */
1263   for (unsigned short idx = ++miterator->current_idx;
1264        idx < miterator->mdict->n_allocated_dictionaries; ++idx)
1265     {
1266       result
1267           = dict_iter_match_first (miterator->mdict->dictionaries[idx],
1268                                          name, &miterator->iterator);
1269       if (result != nullptr)
1270           {
1271             miterator->current_idx = idx;
1272             return result;
1273           }
1274     }
1275 
1276   return nullptr;
1277 }
1278 
1279 /* See dictionary.h.  */
1280 
1281 int
1282 mdict_size (const struct multidictionary *mdict)
1283 {
1284   int size = 0;
1285 
1286   for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx)
1287     size += dict_size (mdict->dictionaries[idx]);
1288 
1289   return size;
1290 }
1291