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