Re: [rfa] struct dictionary

Elena Zannoni
2003-06-09T22:39:15Z

David Carlton writes:
> As promised in
> <http://sources.redhat.com/ml/gdb/2003-04/msg00177.html>, here's the
> 'struct dictionary' patch.
>
> I've tested this on GCC 3.2, DWARF 2, i686-pc-linux-gnu, and have been
> using it on my branch for months. Most of the work is generic; the
> two special cases are jv-lang.c and mdebugread.c. I'm fairly sure I
> got the former right; the mdebugread.c changes are big enough that I
> could easily have slipped up somewhere. (Though I have tested the
> data structures that are used by mdebugread.c but not by buildsym.c.)
> So obviously somebody should test this on a machine using
> mdebugread.c; any volunteers?

Does anybody have a setup for testing mdebug? Daniel?

>
> This is orthogonal to my current namespace patch awaiting review, but
> I will use these mechanisms in my next namespace patch.
>
> David Carlton
> carlton@math.stanford.edu
>
> 2003-04-28 David Carlton <carlton@bactrian.org>
>
> * dictionary.h: New.
> * dictionary.c: New.
> * block.h: Add opaque declaration for struct dictionary.
> (struct block): Add 'dict' member; delete 'hashtable', 'nsyms',
> 'sym' members.
> (BLOCK_DICT): New macro.
> Delete macros BLOCK_HASHTABLE, BLOCK_NSYMS, BLOCK_SYM,
> BLOCK_BUCKETS, BLOCK_BUCKET, BLOCK_HASHTABLE_SIZE,
> BLOCK_SHOULD_SORT.
> (ALL_BLOCK_SYMBOLS): Update definition.
> * Makefile.in (SFILES): Add dictionary.c.
> (dictionary_h): New.
> (COMMON_OBS): Add dictionary.o.
> (dictionary.o): New.
> (ada-lang.o): Depend on dictionary_h.
> (buildsym.o, coffread.o, jv-lang.o, mdebugread.o, objfiles.o)
> (printcmd.o, stack.o, symmisc.o, symtab.o, tracepoint.o)
> (valops.o, mi-cmd-stack.o): Ditto.
> (gdbtk-cmds.o): Update dependencies.
> (gdbtk-stack.o): Ditto.
> * ada-lang.c: Include dictionary.h.
> (symtab_for_sym): Update uses of ALL_BLOCK_SYMBOLS.
> (fill_in_ada_prototype, debug_print_block): Ditto.
> (ada_add_block_symbols): Update uses of ALL_BLOCK_SYMBOLS; replace
> explicit iteration by use of ALL_BLOCK_SYMBOLS. Delete variable
> 'is_sorted'.
> * mdebugread.c: Include dictionary.h.
> (struct parse_stack): Delete 'maxsyms' member.
> (parse_symbol): Update calls to new_block. Delete calls to
> shrink_block. Use dictionary methods.
> (psymtab_to_symtab_1): Delete calls to sort_symtab_syms.
> Update calls to new_symtab. Don't maintain maxsyms data.
> (mylookup_symbol): Update use of ALL_BLOCK_SYMBOLS.
> (add_symbol): Just call dict_add_symbol.
> (new_symtab): Delete 'maxsyms' argument.
> (new_symtab): Update calls to new_block.
> (new_block): Delete 'maxsyms' argument; add 'function' argument.
> (shrink_block): Delete function.
> (fixup_sigtramp): Update call to new_block. Add symbol via
> dict_add_symbol.
> * jv-lang.c: Include dictionary.h.
> (get_java_class_symtab): Set the BLOCK_DICT of the blocks
> appropriately. Set class_symtab->free_func. Make sure the
> blockvector is big enough to hold two blocks.
> (add_class_symtab_symbol): Use dictionary methods.
> (free_class_block): New function.
> (type_from_class): Replace explicit iteration by
> ALL_BLOCK_SYMBOLS.
> * symtab.h (struct symtab): Replace 'free_ptr' method by
> 'free_func'.
> * dwarf2read.c (psymtab_to_symtab_1): Delete call to
> sort_symtab_syms.
> * dwarfread.c (psymtab_to_symtab_1): Delete call to
> sort_symtab_syms.
> * coffread.c (coff_symfile_read): Delete call to sort_symtab_syms.
> Include dictionary.h.
> (patch_opaque_types): Update use of ALL_BLOCK_SYMBOLS.
> * dbxread.c (dbx_psymtab_to_symtab_1): Delete call to
> sort_symtab_syms.
> * objfiles.c: Include dictionary.h.
> (objfile_relocate): Update use of ALL_BLOCK_SYMBOLS.
> * buildsym.c: Include dictionary.h.
> (finish_block): Use dictionary methods.
> (end_symtab): Set free_func to NULL, not free_ptr.
> * tracepoint.c: Include dictionary.h.
> (add_local_symbols): Update use of ALL_BLOCK_SYMBOLS.
> (scope_info): Ditto.
> * stack.c: Include dictionary.h.
> (print_block_frame_locals): Update use of ALL_BLOCK_SYMBOLS.
> (print_block_frame_labels, print_frame_arg_vars): Ditto.
> * symmisc.c (free_symtab_block): Use dictionary methods.
> (dump_symtab): Comment out part where we print size of block and
> update use of ALL_BLOCK_SYMBOLS.
> (free_symtab): Replace use of 'free_ptr' by 'free_func'.
> Include dictionary.h.
> * symfile.h: Delete declarations of sort_block_syms,
> sort_symtab_syms.
> * symfile.c (sort_block_syms): Delete.
> (sort_symtab_syms): Delete.
> * symtab.c: Include dictionary.h.
> (lookup_block_symbol): Use dictionary iterators.
> (find_pc_sect_symtab): Update use of ALL_BLOCK_SYMBOLS.
> (search_symbols, make_symbol_completion_list): Ditto.
> (make_symbol_overload_list): Ditto.
> * printcmd.c (print_frame_args): Update use of ALL_BLOCK_SYMBOLS.
> Include dictionary.h.
> * valops.c (value_of_local): Use dict_empty.
> Include dictionary.h.
>
> 2003-04-28 David Carlton <carlton@bactrian.org>
>
> * mi-cmd-stack.c: Include dictionary.h.
> (list_args_or_locals): Update use of ALL_BLOCK_SYMBOLS.
>
> 2003-04-28 David Carlton <carlton@bactrian.org>
>
> * generic/gdbtk-stack.c: Include dictionary.h.
> (gdb_block_vars): Update use of ALL_BLOCK_SYMBOLS.
> (gdb_get_blocks, gdb_get_vars_command): Ditto.
> * generic/gdbtk-cmds.c: Include dictionary.h.
> (gdb_listfuncs): Update use of ALL_BLOCK_SYMBOLS.
>

As usual, some comments. Could you check in the removal of the
sorting as one patch, and the dictionary as another? See below for
some things, but in general it's ok. I don't feel too
comfortable with the Java stuff, are there any tests that use that
particular code? It sure looks safe to me though.

elena

> --- /dev/null 2002-08-30 16:31:37.000000000 -0700
> +++ dictionary.h 2003-04-30 16:01:20.000000000 -0700
> @@ -0,0 +1,152 @@
> +/* Routines for name->symbol lookups in GDB.
> +
> + Copyright 2003 Free Software Foundation, Inc.
> +
> + Contributed by David Carlton <carlton@bactrian.org> and by Kealia,
> + Inc.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 2 of the License, or (at
> + your option) any later version.
> +
> + This program is distributed in the hope that it will be useful, but
> + WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the Free Software
> + Foundation, Inc., 59 Temple Place - Suite 330,
> + Boston, MA 02111-1307, USA. */
> +
> +#ifndef DICTIONARY_H
> +#define DICTIONARY_H
> +
> +/* An opaque type for dictionaries; only dictionary.c should know
> + about its innards. */
> +
> +struct dictionary;
> +
> +/* Other types needed for declarations. */
> +
> +struct symbol;
> +struct obstack;
> +struct pending;
> +
> +
> +/* The creation functions for various implementations of
> + dictionaries. */
> +
> +/* Create a dictionary implemented via a fixed-size hashtable. All
> + memory it uses is allocated on OBSTACK; the environment is
> + initialized from SYMBOL_LIST. */
> +
> +extern struct dictionary *dict_create_hashed (struct obstack *obstack,
> + const struct pending
> + *symbol_list);
> +
> +/* Create a dictionary implemented via a hashtable that grows as
> + necessary. The dictionary is initially empty; to add symbols to
> + it, call dict_add_symbol(). Call dict_free() when you're done with
> + it. */
> +
> +extern struct dictionary *dict_create_hashed_expandable (void);
> +
> +/* Create a dictionary implemented via a fixed-size array. All memory
> + it uses is allocated on OBSTACK; the environment is initialized
> + from the SYMBOL_LIST. The symbols are ordered in the same order
> + that they're found in SYMBOL_LIST. */
> +
> +extern struct dictionary *dict_create_linear (struct obstack *obstack,
> + const struct pending
> + *symbol_list);
> +
> +/* Create a dictionary implemented via an array that grows as
> + necessary. The dictionary is initially empty; to add symbols to
> + it, call dict_add_symbol(). Call dict_free() when you're done with
> + it. */
> +
> +extern struct dictionary *dict_create_linear_expandable (void);
> +
> +
> +/* The functions providing the interface to dictionaries. Note that
> + the most common parts of the interface, namely symbol lookup, are
> + only provided via iterator functions. */
> +
> +/* Free the memory used by a dictionary that's not on an obstack. (If
> + any.) */
> +
> +extern void dict_free (struct dictionary *dict);
> +
> +/* Add a symbol to an expandable dictionary. */
> +
> +extern void dict_add_symbol (struct dictionary *dict, struct symbol *sym);
> +
> +/* Is the dictionary empty? */
> +
> +extern int dict_empty (struct dictionary *dict);
> +
> +/* A type containing data that is used when iterating over all symbols
> + in a dictionary. Don't ever look at its innards; this type would
> + be opaque if we didn't need to be able to allocate it on the
> + stack. */
> +
> +struct dict_iterator
> +{
> + /* The dictionary that this iterator is associated to. */
> + const struct dictionary *dict;
> + /* The next two members are data that is used in a way that depends
> + on DICT's implementation type. */
> + int index;
> + struct symbol *current;
> +};
> +
> +/* Initialize ITERATOR to point at the first symbol in DICT, and
> + return that first symbol, or NULL if DICT is empty. */
> +
> +extern struct symbol *dict_iterator_first (const struct dictionary *dict,
> + struct dict_iterator *iterator);
> +
> +/* Advance ITERATOR, and return the next symbol, or NULL if there are
> + no more symbols. Don't call this if you've previously received
> + NULL from dict_iterator_first or dict_iterator_next on this
> + iteration. */
> +
> +extern struct symbol *dict_iterator_next (struct dict_iterator *iterator);
> +
> +/* Initialize ITERATOR to point at the first symbol in DICT whose
> + SYMBOL_BEST_NAME is NAME (as tested using strcmp_iw), and return
> + that first symbol, or NULL if there are no such symbols. */
> +
> +extern struct symbol *dict_iter_name_first (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator);
> +
> +/* Advance ITERATOR to point at the next symbol in DICT whose
> + SYMBOL_BEST_NAME is NAME (as tested using strcmp_iw), or NULL if
> + there are no more such symbols. Don't call this if you've
> + previously received NULL from dict_iterator_first or
> + dict_iterator_next on this iteration. And don't call it unless
> + ITERATOR was created by a previous call to dict_iter_name_first
> + with the same NAME. */
> +
> +extern struct symbol *dict_iter_name_next (const char *name,
> + struct dict_iterator *iterator);
> +
> +
> +/* Macro to loop through all symbols in a dictionary DICT, in no
> + particular order. ITER is a struct dict_iterator (NOTE: __not__ a
> + struct dict_iterator *), and SYM points to the current symbol.
> +
> + It's implemented as a single loop, so you can terminate the loop
> + early by a break if you desire. */
> +
> +#define ALL_DICT_SYMBOLS(dict, iter, sym) \
> + for ((sym) = dict_iterator_first ((dict), &(iter)); \
> + (sym); \
> + (sym) = dict_iterator_next (&(iter)))
> +
> +#endif /* DICTIONARY_H */
> --- /dev/null 2002-08-30 16:31:37.000000000 -0700
> +++ dictionary.c 2003-04-28 11:00:23.000000000 -0700
> @@ -0,0 +1,785 @@
> +/* Routines for name->symbol lookups in GDB.
> +
> + Copyright 2003 Free Software Foundation, Inc.
> +
> + Contributed by David Carlton <carlton@bactrian.org> and by Kealia,
> + Inc.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 2 of the License, or (at
> + your option) any later version.
> +
> + This program is distributed in the hope that it will be useful, but
> + WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the Free Software
> + Foundation, Inc., 59 Temple Place - Suite 330,
> + Boston, MA 02111-1307, USA. */
> +
> +#include "defs.h"
> +#include "gdb_obstack.h"
> +#include "symtab.h"
> +#include "buildsym.h"
> +#include "gdb_assert.h"
> +#include "dictionary.h"
> +
> +/* This file implements dictionaries, which are tables that associate
> + symbols to names. They are represented by an opaque type 'struct
> + dictionary'. That type has various internal implementations, which
> + you can choose between depending on what properties you need
> + (e.g. fast lookup, order-preserving, expandable).
> +
> + Each dictionary starts with a 'virtual function table' that
> + contains the functions that actually implement the various
> + operations that dictionaries provide. (Note, however, that, for
> + the sake of client code, we also provide some functions that can be
> + implemented generically in terms of the functions in the vtable.)
> +
> + To add a new dictionary implementation <impl>, what you should do
> + is:
> +
> + * Add a new element DICT_<IMPL> to dict_type.
> +
> + * Create a new structure dictionary_<impl>. If your new
> + implementation is a variant of an existing one, make sure that
> + their structs have the same initial data members. Define accessor
> + macros for your new data members.
> +
> + * Implement all the functions in dict_vtbl as static functions,
> + whose name is the same as the corresponding member of dict_vtbl
> + plus _<impl>. You don't have to do this for those members where
> + you can reuse existing generic functions
> + (e.g. add_symbol_nonexpandable, free_obstack) or in the case where
> + your new implementation is a variant of an existing implementation
> + and where the variant doesn't affect the member function in
> + question.
> +
> + * Define a static const struct dict_vtbl dict_<impl>_vtbl.
> +
> + * Define a function dict_create_<impl> to create these
> + gizmos. Add its declaration to dictionary.h.
> +
> + To add a new operation <op> on all existing implementations, what
> + you should do is:
> +
> + * Add a new member <op> to struct dict_vtbl.
> +
> + * If there is useful generic behavior <op>, define a static
> + function <op>_something_informative that implements that behavior.
> + (E.g. add_symbol_nonexpandable, free_obstack.)
> +
> + * For every implementation <impl> that should have its own specific
> + behavior for <op>, define a static function <op>_<impl>
> + implementing it.
> +
> + * Modify all existing dict_vtbl_<impl>'s to include the appropriate
> + member.
> +
> + * Define a function dict_<op> that looks up <op> in the dict_vtbl
> + and calls the appropriate function. Add a declaration for
> + dict_<op> to dictionary.h.
> +
> +*/
> +
> +/* An enum representing the various implementations of dictionaries.
> + Used only for debugging. */
> +
> +enum dict_type
> + {
> + /* Symbols are stored in a fixed-size hash table. */
> + DICT_HASHED,
> + /* Symbols are stored in an expandable hash table. */
> + DICT_HASHED_EXPANDABLE,
> + /* Symbols are stored in a fixed-size array. */
> + DICT_LINEAR,
> + /* Symbols are stored in an expandable array. */
> + DICT_LINEAR_EXPANDABLE,
> + };
> +
> +/* The virtual function table. */
> +
> +struct dict_vtbl
> +{
> + /* The type of the dictionary. This is only here to make debugging
> + a bit easier; it's not actually used. */
> + enum dict_type type;
> + /* The function to free a dictionary. */
> + void (*free) (struct dictionary *dict);
> + /* Add a symbol to a dictionary, if possible. */
> + void (*add_symbol) (struct dictionary *dict, struct symbol *sym);
> + /* Iterator functions. */
> + struct symbol *(*iterator_first) (const struct dictionary *dict,
> + struct dict_iterator *iterator);
> + struct symbol *(*iterator_next) (struct dict_iterator *iterator);
> + /* Functions to iterate over symbols with a given name. */
> + struct symbol *(*iter_name_first) (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator);
> + struct symbol *(*iter_name_next) (const char *name,
> + struct dict_iterator *iterator);
> +};
> +
> +/* Now comes the structs used to store the data for different
> + implementations. If two implementations have data in common, put
> + the common data at the top of their structs, ordered in the same
> + way. */
> +
> +struct dictionary_hashed
> +{
> + int nbuckets;
> + struct symbol **buckets;
> +};
> +
> +struct dictionary_hashed_expandable
> +{
> + /* How many buckets we currently have. */
> + int nbuckets;
> + struct symbol **buckets;
> + /* How many syms we currently have; we need this so we will know
> + when to add more buckets. */
> + int nsyms;
> +};
> +
> +struct dictionary_linear
> +{
> + int nsyms;
> + struct symbol **syms;
> +};
> +
> +struct dictionary_linear_expandable
> +{
> + /* How many symbols we currently have. */
> + int nsyms;
> + struct symbol **syms;
> + /* How many symbols we can store before needing to reallocate. */
> + int capacity;
> +};
> +
> +/* And now, the star of our show. */
> +
> +struct dictionary
> +{
> + const struct dict_vtbl *vtbl;
> + union
> + {
> + struct dictionary_hashed hashed;
> + struct dictionary_hashed_expandable hashed_expandable;
> + struct dictionary_linear linear;
> + struct dictionary_linear_expandable linear_expandable;
> + }
> + data;
> +};
> +
> +/* Accessor macros. */
> +
> +#define DICT_VTBL(d) (d)->vtbl
> +
> +/* These can be used for DICT_HASHED_EXPANDABLE, too. */
> +
> +#define DICT_HASHED_NBUCKETS(d) (d)->data.hashed.nbuckets
> +#define DICT_HASHED_BUCKETS(d) (d)->data.hashed.buckets
> +#define DICT_HASHED_BUCKET(d,i) DICT_HASHED_BUCKETS (d) [i]
> +
> +#define DICT_HASHED_EXPANDABLE_NSYMS(d) (d)->data.hashed_expandable.nsyms
> +
> +/* These can be used for DICT_LINEAR_EXPANDABLEs, too. */
> +
> +#define DICT_LINEAR_NSYMS(d) (d)->data.linear.nsyms
> +#define DICT_LINEAR_SYMS(d) (d)->data.linear.syms
> +#define DICT_LINEAR_SYM(d,i) DICT_LINEAR_SYMS (d) [i]
> +
> +#define DICT_LINEAR_EXPANDABLE_CAPACITY(d) \
> + (d)->data.linear_expandable.capacity
> +
> +/* The initial size of a DICT_*_EXPANDABLE dictionary. */
> +
> +#define DICT_EXPANDABLE_INITIAL_CAPACITY 10
> +
> +/* This calculates the number of buckets we'll use in a hashtable,
> + given the number of symbols that it will contain. */
> +
> +#define DICT_HASHTABLE_SIZE(n) ((n)/5 + 1)
> +
> +/* Accessor macros for dict_iterators; they're here rather than
> + dictionary.h because code elsewhere should treat dict_iterators as
> + opaque. */
> +
> +/* The dictionary that the iterator is associated to. */
> +#define DICT_ITERATOR_DICT(iter) (iter)->dict
> +/* For linear dictionaries, the index of the last symbol returned; for
> + hashed dictionaries, the bucket of the last symbol returned. */
> +#define DICT_ITERATOR_INDEX(iter) (iter)->index
> +/* For hashed dictionaries, this points to the last symbol returned;
> + otherwise, this is unused. */
> +#define DICT_ITERATOR_CURRENT(iter) (iter)->current
> +
> +/* Declarations of functions for vtbls. */
> +
> +/* Functions that might work across a range of dictionary types. */
> +
> +static void add_symbol_nonexpandable (struct dictionary *dict,
> + struct symbol *sym);
> +
> +static void free_obstack (struct dictionary *dict);
> +
> +/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE
> + dictionaries. */
> +
> +static struct symbol *iterator_first_hashed (const struct dictionary *dict,
> + struct dict_iterator *iterator);
> +
> +static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
> +
> +static struct symbol *iter_name_first_hashed (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator);
> +
> +static struct symbol *iter_name_next_hashed (const char *name,
> + struct dict_iterator *iterator);
> +
> +/* Functions only for DICT_HASHED_EXPANDABLE. */
> +
> +static void free_hashed_expandable (struct dictionary *dict);
> +
> +static void add_symbol_hashed_expandable (struct dictionary *dict,
> + struct symbol *sym);
> +
> +/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE
> + dictionaries. */
> +
> +static struct symbol *iterator_first_linear (const struct dictionary *dict,
> + struct dict_iterator *iterator);
> +
> +static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
> +
> +static struct symbol *iter_name_first_linear (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator);
> +
> +static struct symbol *iter_name_next_linear (const char *name,
> + struct dict_iterator *iterator);
> +
> +
> +/* Functions only for DICT_LINEAR_EXPANDABLE. */
> +
> +static void free_linear_expandable (struct dictionary *dict);
> +
> +static void add_symbol_linear_expandable (struct dictionary *dict,
> + struct symbol *sym);
> +
> +/* Various vtbls that we'll actually use. */
> +
> +static const struct dict_vtbl dict_hashed_vtbl =
> + {
> + DICT_HASHED, free_obstack, add_symbol_nonexpandable,
> + iterator_first_hashed, iterator_next_hashed,
> + iter_name_first_hashed, iter_name_next_hashed,
> + };
> +

Could you do these one per line and put a comment with the field name
next to it (for easy grepping)? I am not too fond of the use of vtable
terminology, could you use 'vector' or something else?

> +static const struct dict_vtbl dict_hashed_expandable_vtbl =
> + {
> + DICT_HASHED_EXPANDABLE, free_hashed_expandable,
> + add_symbol_hashed_expandable,
> + iterator_first_hashed, iterator_next_hashed,
> + iter_name_first_hashed, iter_name_next_hashed,
> + };
> +
> +static const struct dict_vtbl dict_linear_vtbl =
> + {
> + DICT_LINEAR, free_obstack, add_symbol_nonexpandable,
> + iterator_first_linear, iterator_next_linear,
> + iter_name_first_linear, iter_name_next_linear,
> + };
> +
> +static const struct dict_vtbl dict_linear_expandable_vtbl =
> + {
> + DICT_LINEAR_EXPANDABLE, free_linear_expandable,
> + add_symbol_linear_expandable,
> + iterator_first_linear, iterator_next_linear,
> + iter_name_first_linear, iter_name_next_linear,
> + };
> +
> +/* Declarations of helper functions (i.e. ones that don't go into
> + vtbls). */
> +
> +static struct symbol *iterator_hashed_advance (struct dict_iterator *iter);
> +
> +static void insert_symbol_hashed (struct dictionary *dict,
> + struct symbol *sym);
> +
> +static void expand_hashtable (struct dictionary *dict);
> +
> +/* The creation functions. */
> +
> +/* Create a dictionary implemented via a fixed-size hashtable. All
> + memory it uses is allocated on OBSTACK; the environment is
> + initialized from SYMBOL_LIST. */
> +
> +struct dictionary *
> +dict_create_hashed (struct obstack *obstack,
> + const struct pending *symbol_list)
> +{
> + struct dictionary *retval;
> + int nsyms = 0, nbuckets, i;
> + struct symbol **buckets;
> + const struct pending *list_counter;
> +
> + retval = obstack_alloc (obstack, sizeof (struct dictionary));
> + DICT_VTBL (retval) = &dict_hashed_vtbl;
> +
> + /* Calculate the number of symbols, and allocate space for them. */
> + for (list_counter = symbol_list;
> + list_counter != NULL;
> + list_counter = list_counter->next)
> + {
> + nsyms += list_counter->nsyms;
> + }
> + nbuckets = DICT_HASHTABLE_SIZE (nsyms);
> + DICT_HASHED_NBUCKETS (retval) = nbuckets;
> + buckets = obstack_alloc (obstack, nbuckets * sizeof (struct symbol *));
> + memset (buckets, 0, nbuckets * sizeof (struct symbol *));
> + DICT_HASHED_BUCKETS (retval) = buckets;
> +
> + /* Now fill the buckets. */
> + for (list_counter = symbol_list;
> + list_counter != NULL;
> + list_counter = list_counter->next)
> + {
> + for (i = list_counter->nsyms - 1; i >= 0; --i)
> + {
> + insert_symbol_hashed (retval, list_counter->symbol[i]);
> + }
> + }
> +
> + return retval;
> +}
> +
> +/* Create a dictionary implemented via a hashtable that grows as
> + necessary. The dictionary is initially empty; to add symbols to
> + it, call dict_add_symbol(). Call dict_free() when you're done with
> + it. */
> +
> +extern struct dictionary *
> +dict_create_hashed_expandable (void)
> +{
> + struct dictionary *retval;
> +
> + retval = xmalloc (sizeof (struct dictionary));
> + DICT_VTBL (retval) = &dict_hashed_expandable_vtbl;
> + DICT_HASHED_NBUCKETS (retval) = DICT_EXPANDABLE_INITIAL_CAPACITY;
> + DICT_HASHED_BUCKETS (retval) = xcalloc (DICT_EXPANDABLE_INITIAL_CAPACITY,
> + sizeof (struct symbol *));
> + DICT_HASHED_EXPANDABLE_NSYMS (retval) = 0;
> +
> + return retval;
> +}
> +
> +/* Create a dictionary implemented via a fixed-size array. All memory
> + it uses is allocated on OBSTACK; the environment is initialized
> + from the SYMBOL_LIST. The symbols are ordered in the same order
> + that they're found in SYMBOL_LIST. */
> +
> +struct dictionary *
> +dict_create_linear (struct obstack *obstack,
> + const struct pending *symbol_list)
> +{
> + struct dictionary *retval;
> + int nsyms = 0, i, j;
> + struct symbol **syms;
> + const struct pending *list_counter;
> +
> + retval = obstack_alloc (obstack, sizeof (struct dictionary));
> + DICT_VTBL (retval) = &dict_linear_vtbl;
> +
> + /* Calculate the number of symbols, and allocate space for them. */
> + for (list_counter = symbol_list;
> + list_counter != NULL;
> + list_counter = list_counter->next)
> + {
> + nsyms += list_counter->nsyms;
> + }
> + DICT_LINEAR_NSYMS (retval) = nsyms;
> + syms = obstack_alloc (obstack, nsyms * sizeof (struct symbol *));
> + DICT_LINEAR_SYMS (retval) = syms;
> +
> + /* Now fill in the symbols. Start filling in from the back, so as
> + to preserve the original order of the symbols. */
> + for (list_counter = symbol_list, j = nsyms - 1;
> + list_counter != NULL;
> + list_counter = list_counter->next)
> + {
> + for (i = list_counter->nsyms - 1;
> + i >= 0;
> + --i, --j)
> + {
> + syms[j] = list_counter->symbol[i];
> + }
> + }
> +
> + return retval;
> +}
> +
> +/* Create a dictionary implemented via an array that grows as
> + necessary. The dictionary is initially empty; to add symbols to
> + it, call dict_add_symbol(). Call dict_free() when you're done with
> + it. */
> +
> +struct dictionary *
> +dict_create_linear_expandable (void)
> +{
> + struct dictionary *retval;
> +
> + retval = xmalloc (sizeof (struct dictionary));
> + DICT_VTBL (retval) = &dict_linear_expandable_vtbl;
> + DICT_LINEAR_NSYMS (retval) = 0;
> + DICT_LINEAR_EXPANDABLE_CAPACITY (retval)
> + = DICT_EXPANDABLE_INITIAL_CAPACITY;
> + DICT_LINEAR_SYMS (retval)
> + = xmalloc (DICT_LINEAR_EXPANDABLE_CAPACITY (retval)
> + * sizeof (struct symbol *));
> +
> + return retval;
> +}
> +
> +/* The functions providing the dictionary interface. */
> +
> +/* Free the memory used by a dictionary that's not on an obstack. (If
> + any.) */
> +
> +void
> +dict_free (struct dictionary *dict)
> +{
> + (DICT_VTBL (dict))->free (dict);
> +}
> +
> +/* Add SYM to DICT. DICT had better be expandable. */
> +
> +void
> +dict_add_symbol (struct dictionary *dict, struct symbol *sym)
> +{
> + (DICT_VTBL (dict))->add_symbol (dict, sym);
> +}
> +
> +/* Initialize ITERATOR to point at the first symbol in DICT, and
> + return that first symbol, or NULL if DICT is empty. */
> +
> +struct symbol *
> +dict_iterator_first (const struct dictionary *dict,
> + struct dict_iterator *iterator)
> +{
> + return (DICT_VTBL (dict))->iterator_first (dict, iterator);
> +}
> +
> +/* Advance ITERATOR, and return the next symbol, or NULL if there are
> + no more symbols. */
> +
> +struct symbol *
> +dict_iterator_next (struct dict_iterator *iterator)
> +{
> + return (DICT_VTBL (DICT_ITERATOR_DICT (iterator)))
> + ->iterator_next (iterator);
> +}
> +
> +struct symbol *
> +dict_iter_name_first (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator)
> +{
> + return (DICT_VTBL (dict))->iter_name_first (dict, name, iterator);
> +}
> +
> +struct symbol *
> +dict_iter_name_next (const char *name, struct dict_iterator *iterator)
> +{
> + return (DICT_VTBL (DICT_ITERATOR_DICT (iterator)))
> + ->iter_name_next (name, iterator);
> +}
> +
> +/* Now come functions (well, one function, currently) that are
> + implemented generically by means of the vtable. Typically, they're
> + rarely used. */
> +
> +/* Test to see if DICT is empty. */
> +
> +int
> +dict_empty (struct dictionary *dict)
> +{
> + struct dict_iterator iter;
> +
> + return (dict_iterator_first (dict, &iter) == NULL);
> +}
> +
> +
> +/* The functions implementing the dictionary interface. */
> +
> +/* Generic functions, where appropriate. */
> +
> +static void
> +free_obstack (struct dictionary *dict)
> +{
> + /* Do nothing! */
> +}
> +
> +static void
> +add_symbol_nonexpandable (struct dictionary *dict, struct symbol *sym)
> +{
> + internal_error (__FILE__, __LINE__,
> + "dict_add_symbol: non-expandable dictionary");
> +}
> +
> +/* Functions for DICT_HASHED and DICT_HASHED_EXPANDABLE. */
> +
> +static struct symbol *
> +iterator_first_hashed (const struct dictionary *dict,
> + struct dict_iterator *iterator)
> +{
> + DICT_ITERATOR_DICT (iterator) = dict;
> + DICT_ITERATOR_INDEX (iterator) = -1;
> + return iterator_hashed_advance (iterator);
> +}
> +
> +static struct symbol *
> +iterator_next_hashed (struct dict_iterator *iterator)
> +{
> + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
> + struct symbol *next;
> +
> + next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
> +
> + if (next == NULL)
> + return iterator_hashed_advance (iterator);
> + else
> + {
> + DICT_ITERATOR_CURRENT (iterator) = next;
> + return next;
> + }
> +}
> +
> +static struct symbol *
> +iterator_hashed_advance (struct dict_iterator *iterator)
> +{
> + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
> + int nbuckets = DICT_HASHED_NBUCKETS (dict);
> + int i;
> +
> + for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nbuckets; ++i)
> + {
> + struct symbol *sym = DICT_HASHED_BUCKET (dict, i);
> +
> + if (sym != NULL)
> + {
> + DICT_ITERATOR_INDEX (iterator) = i;
> + DICT_ITERATOR_CURRENT (iterator) = sym;
> + return sym;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +static struct symbol *
> +iter_name_first_hashed (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator)
> +{
> + unsigned int hash_index
> + = msymbol_hash_iw (name) % DICT_HASHED_NBUCKETS (dict);
> + struct symbol *sym;
> +
> + DICT_ITERATOR_DICT (iterator) = dict;
> +
> + /* Loop through the symbols in the given bucket, breaking when SYM
> + first matches. If SYM never matches, it will be set to NULL;
> + either way, we have the right return value. */
> +
> + for (sym = DICT_HASHED_BUCKET (dict, hash_index);
> + sym != NULL;
> + sym = sym->hash_next)
> + {
> + /* Warning: the order of arguments to strcmp_iw matters! */
> + if (strcmp_iw (SYMBOL_NATURAL_NAME (sym), name) == 0)
> + {
> + break;
> + }
> +
> + }
> +
> + DICT_ITERATOR_CURRENT (iterator) = sym;
> + return sym;
> +}
> +
> +static struct symbol *
> +iter_name_next_hashed (const char *name, struct dict_iterator *iterator)
> +{
> + struct symbol *next;
> +
> + for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
> + next != NULL;
> + next = next->hash_next)
> + {
> + if (strcmp_iw (SYMBOL_NATURAL_NAME (next), name) == 0)
> + break;
> + }
> +
> + DICT_ITERATOR_CURRENT (iterator) = next;
> +
> + return next;
> +}
> +
> +/* Insert SYM into DICT. */
> +
> +static void
> +insert_symbol_hashed (struct dictionary *dict,
> + struct symbol *sym)
> +{
> + unsigned int hash_index;
> + struct symbol **buckets = DICT_HASHED_BUCKETS (dict);
> +
> + hash_index = (msymbol_hash_iw (SYMBOL_NATURAL_NAME (sym))
> + % DICT_HASHED_NBUCKETS (dict));
> + sym->hash_next = buckets[hash_index];
> + buckets[hash_index] = sym;
> +}
> +
> +/* Functions only for DICT_HASHED_EXPANDABLE. */
> +
> +static void
> +free_hashed_expandable (struct dictionary *dict)
> +{
> + xfree (DICT_HASHED_BUCKETS (dict));
> + xfree (dict);
> +}
> +
> +static void
> +add_symbol_hashed_expandable (struct dictionary *dict,
> + struct symbol *sym)
> +{
> + int nsyms = ++DICT_HASHED_EXPANDABLE_NSYMS (dict);
> +
> + if (DICT_HASHTABLE_SIZE (nsyms) > DICT_HASHED_NBUCKETS (dict))
> + expand_hashtable (dict);
> +
> + insert_symbol_hashed (dict, sym);
> + DICT_HASHED_EXPANDABLE_NSYMS (dict) = nsyms;
> +}
> +
> +static void
> +expand_hashtable (struct dictionary *dict)
> +{
> + int old_nbuckets = DICT_HASHED_NBUCKETS (dict);
> + struct symbol **old_buckets = DICT_HASHED_BUCKETS (dict);
> + int new_nbuckets = 2*old_nbuckets + 1;
> + struct symbol **new_buckets = xcalloc (new_nbuckets,
> + sizeof (struct symbol *));
> + int i;
> +
> + DICT_HASHED_NBUCKETS (dict) = new_nbuckets;
> + DICT_HASHED_BUCKETS (dict) = new_buckets;
> +
> + for (i = 0; i < old_nbuckets; ++i) {
> + struct symbol *sym, *next_sym;
> +
> + sym = old_buckets[i];
> + if (sym != NULL) {
> + for (next_sym = sym->hash_next;
> + next_sym != NULL;
> + next_sym = sym->hash_next) {
> + insert_symbol_hashed (dict, sym);
> + sym = next_sym;
> + }
> +
> + insert_symbol_hashed (dict, sym);
> + }
> + }
> +
> + xfree (old_buckets);
> +}
> +
> +/* Functions for DICT_LINEAR and DICT_LINEAR_EXPANDABLE. */
> +
> +static struct symbol *
> +iterator_first_linear (const struct dictionary *dict,
> + struct dict_iterator *iterator)
> +{
> + DICT_ITERATOR_DICT (iterator) = dict;
> + DICT_ITERATOR_INDEX (iterator) = 0;
> + return DICT_LINEAR_NSYMS (dict) ? DICT_LINEAR_SYM (dict, 0) : NULL;
> +}
> +
> +static struct symbol *
> +iterator_next_linear (struct dict_iterator *iterator)
> +{
> + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
> +
> + if (++DICT_ITERATOR_INDEX (iterator) >= DICT_LINEAR_NSYMS (dict))
> + return NULL;
> + else
> + return DICT_LINEAR_SYM (dict, DICT_ITERATOR_INDEX (iterator));
> +}
> +
> +static struct symbol *
> +iter_name_first_linear (const struct dictionary *dict,
> + const char *name,
> + struct dict_iterator *iterator)
> +{
> + DICT_ITERATOR_DICT (iterator) = dict;
> + DICT_ITERATOR_INDEX (iterator) = -1;
> +
> + return iter_name_next_linear (name, iterator);
> +}
> +
> +static struct symbol *
> +iter_name_next_linear (const char *name, struct dict_iterator *iterator)
> +{
> + const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
> + int i, nsyms = DICT_LINEAR_NSYMS (dict);
> + struct symbol *sym, *retval = NULL;
> +
> + for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i)
> + {
> + sym = DICT_LINEAR_SYM (dict, i);
> + if (strcmp_iw (SYMBOL_NATURAL_NAME (sym), name) == 0)
> + {
> + retval = sym;
> + break;
> + }
> + }
> +
> + DICT_ITERATOR_INDEX (iterator) = i;
> +
> + return retval;
> +}
> +
> +/* Functions only for DICT_LINEAR_EXPANDABLE. */
> +
> +static void
> +free_linear_expandable (struct dictionary *dict)
> +{
> + xfree (DICT_LINEAR_SYMS (dict));
> + xfree (dict);
> +}
> +
> +
> +static void
> +add_symbol_linear_expandable (struct dictionary *dict,
> + struct symbol *sym)
> +{
> + int nsyms = ++DICT_LINEAR_NSYMS (dict);
> +
> + /* Do we have enough room? If not, grow it. */
> + if (nsyms > DICT_LINEAR_EXPANDABLE_CAPACITY (dict)) {
> + DICT_LINEAR_EXPANDABLE_CAPACITY (dict) *= 2;
> + DICT_LINEAR_SYMS (dict)
> + = xrealloc (DICT_LINEAR_SYMS (dict),
> + DICT_LINEAR_EXPANDABLE_CAPACITY (dict)
> + * sizeof (struct symbol *));
> + }
> +
> + DICT_LINEAR_SYM (dict, nsyms - 1) = sym;
> +}
> Index: Makefile.in
> ===================================================================
> RCS file: /cvs/src/src/gdb/Makefile.in,v
> retrieving revision 1.366
> diff -u -p -r1.366 Makefile.in
> --- Makefile.in 25 Apr 2003 03:30:16 -0000 1.366
> +++ Makefile.in 30 Apr 2003 22:45:30 -0000
> @@ -513,7 +513,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
> charset.c cli-out.c coffread.c coff-pe-read.c \
> complaints.c completer.c corefile.c \
> cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \
> - dbxread.c demangle.c disasm.c doublest.c \
> + dbxread.c demangle.c dictionary.c disasm.c doublest.c \
> dummy-frame.c dwarfread.c dwarf2expr.c dwarf2loc.c dwarf2read.c \
> elfread.c environ.c eval.c event-loop.c event-top.c expprint.c \
> f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c frame.c \
> @@ -631,6 +631,7 @@ dcache_h = dcache.h
> defs_h = defs.h $(config_h) $(gdb_locale_h) $(gdb_signals_h) $(ansidecl_h) \
> $(libiberty_h) $(progress_h) $(bfd_h) $(tui_h) $(ui_file_h) $(xm_h) \
> $(nm_h) $(tm_h) $(fopen_same_h) $(gdbarch_h) $(arch_utils_h)
> +dictionary_h = dictionary.h
> disasm_h = disasm.h
> doublest_h = doublest.h $(floatformat_h)
> dst_h = dst.h
> @@ -837,7 +838,7 @@ TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRC
> COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
> charset.o disasm.o dummy-frame.o \
> source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
> - block.o symtab.o symfile.o symmisc.o linespec.o \
> + block.o symtab.o symfile.o symmisc.o linespec.o dictionary.o \
> infcall.o \
> infcmd.o infrun.o \
> expprint.o environ.o stack.o thread.o \
> @@ -1494,7 +1495,7 @@ ada-lang.o: ada-lang.c $(gdb_string_h) $
> $(gdbtypes_h) $(gdbcmd_h) $(expression_h) $(parser_defs_h) \
> $(language_h) $(c_lang_h) $(inferior_h) $(symfile_h) $(objfiles_h) \
> $(breakpoint_h) $(gdbcore_h) $(ada_lang_h) $(ui_out_h) $(block_h) \
> - $(infcall_h)
> + $(infcall_h) $(dictionary.h)

dictionary_h

> ada-tasks.o: ada-tasks.c $(defs_h) $(command_h) $(value_h) $(language_h) \
> $(inferior_h) $(symtab_h) $(target_h) $(gdbcore_h) $(gregset_h) \
> $(ada_lang_h)
> @@ -1575,7 +1576,7 @@ buildsym.o: buildsym.c $(defs_h) $(bfd_h
> $(symfile_h) $(objfiles_h) $(gdbtypes_h) $(gdb_assert_h) \
> $(complaints_h) $(gdb_string_h) $(expression_h) $(language_h) \
> $(bcache_h) $(filenames_h) $(macrotab_h) $(demangle_h) $(buildsym_h) \
> - $(stabsread_h) $(block_h) $(cp_support_h)
> + $(stabsread_h) $(block_h) $(cp_support_h) $(dictionary_h)
> builtin-regs.o: builtin-regs.c $(defs_h) $(builtin_regs_h) $(gdbtypes_h) \
> $(gdb_string_h) $(gdb_assert_h)
> c-lang.o: c-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
> @@ -1599,7 +1600,8 @@ coffread.o: coffread.c $(defs_h) $(symta
> $(breakpoint_h) $(bfd_h) $(gdb_obstack_h) $(gdb_string_h) \
> $(coff_internal_h) $(libcoff_h) $(symfile_h) $(objfiles_h) \
> $(buildsym_h) $(gdb_stabs_h) $(stabsread_h) $(complaints_h) \
> - $(target_h) $(gdb_assert_h) $(block_h) $(coff_pe_read_h)
> + $(target_h) $(gdb_assert_h) $(block_h) $(dictionary_h) \
> + $(coff_pe_read_h)
> coff-pe-read.o: coff-pe-read.c $(bfd_h) $(defs_h) $(symtab_h) \
> $(gdbtypes_h) $(symfile_h) $(objfiles_h) $(coff_pe_read_h)
> complaints.o: complaints.c $(defs_h) $(complaints_h) $(gdb_assert_h) \
> @@ -1653,6 +1655,8 @@ dcache.o: dcache.c $(defs_h) $(dcache_h)
> delta68-nat.o: delta68-nat.c $(defs_h)
> demangle.o: demangle.c $(defs_h) $(command_h) $(gdbcmd_h) $(demangle_h) \
> $(gdb_string_h)
> +dictionary.o: dictionary.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
> + $(buildsym_h) $(gdb_assert_h) $(dictionary_h)
> dink32-rom.o: dink32-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
> $(serial_h) $(symfile_h) $(inferior_h) $(regcache_h)
> disasm.o: disasm.c $(defs_h) $(gdb_string_h) $(target_h) $(value_h) \
> @@ -1869,7 +1873,7 @@ irix5-nat.o: irix5-nat.c $(defs_h) $(inf
> jv-lang.o: jv-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
> $(parser_defs_h) $(language_h) $(gdbtypes_h) $(symtab_h) \
> $(symfile_h) $(objfiles_h) $(gdb_string_h) $(value_h) $(c_lang_h) \
> - $(jv_lang_h) $(gdbcore_h) $(block_h) $(demangle_h)
> + $(jv_lang_h) $(gdbcore_h) $(block_h) $(demangle_h) $(dictionary_h)
> jv-typeprint.o: jv-typeprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
> $(value_h) $(demangle_h) $(jv_lang_h) $(gdb_string_h) $(typeprint_h) \
> $(c_lang_h) $(cp_abi_h)
> @@ -1949,7 +1953,7 @@ mcore-tdep.o: mcore-tdep.c $(defs_h) $(f
> mdebugread.o: mdebugread.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
> $(symfile_h) $(objfiles_h) $(gdb_obstack_h) $(buildsym_h) \
> $(stabsread_h) $(complaints_h) $(demangle_h) $(gdb_assert_h) \
> - $(block_h) \
> + $(block_h) $(dictionary_h) \
> $(coff_sym_h) $(coff_symconst_h) $(gdb_stat_h) $(gdb_string_h) \
> $(bfd_h) $(coff_ecoff_h) $(libaout_h) $(aout_aout64_h) \
> $(aout_stab_gnu_h) $(expression_h) $(language_h)
> @@ -2010,7 +2014,7 @@ objc-lang.o: objc-lang.c $(defs_h) $(sym
> objfiles.o: objfiles.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \
> $(objfiles_h) $(gdb_stabs_h) $(target_h) $(bcache_h) $(gdb_stat_h) \
> $(gdb_obstack_h) $(gdb_string_h) $(breakpoint_h) $(mmalloc_h) \
> - $(block_h)
> + $(block_h) $(dictionary_h)
> observer.o: observer.c $(observer_h) $(defs_h)
> ocd.o: ocd.c $(defs_h) $(gdbcore_h) $(gdb_string_h) $(frame_h) $(inferior_h) \
> $(bfd_h) $(symfile_h) $(target_h) $(gdbcmd_h) $(objfiles_h) \
> @@ -2061,7 +2065,7 @@ printcmd.o: printcmd.c $(defs_h) $(gdb_s
> $(gdbtypes_h) $(value_h) $(language_h) $(expression_h) $(gdbcore_h) \
> $(gdbcmd_h) $(target_h) $(breakpoint_h) $(demangle_h) $(valprint_h) \
> $(annotate_h) $(symfile_h) $(objfiles_h) $(completer_h) $(ui_out_h) \
> - $(gdb_assert_h) $(block_h)
> + $(gdb_assert_h) $(block_h) $(dictionary_h)
> proc-api.o: proc-api.c $(defs_h) $(gdbcmd_h) $(completer_h) $(gdb_wait_h) \
> $(proc_utils_h)
> proc-events.o: proc-events.c $(defs_h)
> @@ -2248,7 +2252,7 @@ stabsread.o: stabsread.c $(defs_h) $(gdb
> stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \
> $(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_h) \
> $(gdbcore_h) $(target_h) $(breakpoint_h) $(demangle_h) $(inferior_h) \
> - $(annotate_h) $(ui_out_h) $(source_h) $(block_h)
> + $(annotate_h) $(ui_out_h) $(source_h) $(block_h) $(dictionary_h)
> standalone.o: standalone.c $(gdb_stat_h) $(defs_h) $(symtab_h) $(frame_h) \
> $(inferior_h) $(gdb_wait_h)
> std-regs.o: std-regs.c $(defs_h) $(builtin_regs_h) $(frame_h) $(gdbtypes_h) \
> @@ -2269,13 +2273,13 @@ symm-tdep.o: symm-tdep.c $(defs_h) $(fra
> symmisc.o: symmisc.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(bfd_h) \
> $(symfile_h) $(objfiles_h) $(breakpoint_h) $(command_h) \
> $(gdb_obstack_h) $(language_h) $(bcache_h) $(gdb_string_h) \
> - $(readline_h) $(block_h) $(gdb_regex_h)
> + $(readline_h) $(block_h) $(gdb_regex_h) $(dictionary_h)
> symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
> $(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
> $(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
> $(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
> $(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
> - $(cp_abi_h) $(source_h) $(block_h)
> + $(cp_abi_h) $(source_h) $(block_h) $(dictionary_h)
> target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
> $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
> $(gdb_wait_h) $(dcache_h) $(regcache_h)
> @@ -2296,7 +2300,7 @@ tracepoint.o: tracepoint.c $(defs_h) $(s
> $(expression_h) $(gdbcmd_h) $(value_h) $(target_h) $(language_h) \
> $(gdb_string_h) $(inferior_h) $(tracepoint_h) $(remote_h) \
> $(linespec_h) $(regcache_h) $(completer_h) $(gdb_events_h) \
> - $(block_h) $(ax_h) $(ax_gdb_h) $(readline_h)
> + $(block_h) $(dictionary_h) $(ax_h) $(ax_gdb_h) $(readline_h)
> typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
> $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(command_h) \
> $(gdbcmd_h) $(target_h) $(language_h) $(cp_abi_h) $(gdb_string_h)
> @@ -2321,7 +2325,7 @@ valarith.o: valarith.c $(defs_h) $(value
> valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \
> $(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \
> $(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(gdb_string_h) \
> - $(gdb_assert_h) $(block_h)
> + $(gdb_assert_h) $(block_h) $(dictionary_h)
> valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
> $(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \
> $(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h)
> @@ -2488,9 +2492,10 @@ gdbtk-bp.o: $(srcdir)/gdbtk/generic/gdbt
>
> gdbtk-cmds.o: $(srcdir)/gdbtk/generic/gdbtk-cmds.c \
> $(srcdir)/gdbtk/generic/gdbtk.h $(srcdir)/gdbtk/generic/gdbtk-cmds.h \
> - $(defs_h) $(symtab_h) $(inferior_h) \
> - $(command_h) $(bfd_h) $(top_h) $(symfile_h) $(objfiles_h) $(target_h) \
> - $(gdb_string_h) $(tracepoint_h) $(source_h) $(regcache_h)
> + $(defs_h) $(inferior_h) $(source_h) $(symfile_h) $(objfiles_h) \
> + $(gdbcore_h) $(demangle_h) $(linespec_h) $(tui_file_h) $(top_h) \
> + $(annotate_h) $(block_h) $(dictionary_h) $(gdb_string_h) \
> + $(dis_asm_h) $(gdbcmd_h)
> $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
> $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \
> $(GDBTK_CFLAGS) $(srcdir)/gdbtk/generic/gdbtk-cmds.c \
> @@ -2531,8 +2536,8 @@ gdbtk-register.o: $(srcdir)/gdbtk/generi
> gdbtk-stack.o: $(srcdir)/gdbtk/generic/gdbtk-stack.c \
> $(srcdir)/gdbtk/generic/gdbtk.h $(srcdir)/gdbtk/generic/gdbtk-cmds.h \
> $(srcdir)/gdbtk/generic/gdbtk-wrapper.h \
> - $(defs_h) $(frame_h) $(value_h) $(target_h) $(breakpoint_h) \
> - $(linespec_h)
> + $(defs_h) $(target_h) $(breakpoint_h) $(linespec_h) \
> + $(block_h) $(dictionary_h)
> $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(ITCL_CFLAGS) \
> $(TCL_CFLAGS) $(TK_CFLAGS) $(X11_CFLAGS) \
> $(GDBTK_CFLAGS) $(srcdir)/gdbtk/generic/gdbtk-stack.c \
> @@ -2573,7 +2578,8 @@ mi-cmd-env.o: $(srcdir)/mi/mi-cmd-env.c
> $(environ_h) $(command_h) $(ui_out_h) $(top_h) $(gdb_string_h)
> $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-env.c
> mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stack.c $(defs_h) $(target_h) $(frame_h) \
> - $(value_h) $(mi_cmds_h) $(ui_out_h) $(symtab_h) $(block_h)
> + $(value_h) $(mi_cmds_h) $(ui_out_h) $(symtab_h) $(block_h) \
> + $(dictionary_h)
> $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-stack.c
> mi-cmd-var.o: $(srcdir)/mi/mi-cmd-var.c $(defs_h) $(mi_cmds_h) $(ui_out_h) \
> $(mi_out_h) $(varobj_h) $(value_h) $(gdb_string_h)
> Index: ada-lang.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/ada-lang.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 ada-lang.c
> --- ada-lang.c 21 Apr 2003 16:48:37 -0000 1.24
> +++ ada-lang.c 30 Apr 2003 22:45:38 -0000
> @@ -40,6 +40,7 @@ Foundation, Inc., 675 Mass Ave, Cambridg
> #include "ui-out.h"
> #include "block.h"
> #include "infcall.h"
> +#include "dictionary.h"
>
> struct cleanup *unresolved_names;
>
> @@ -3434,7 +3435,8 @@ symtab_for_sym (struct symbol *sym)
> struct objfile *objfile;
> struct block *b;
> struct symbol *tmp_sym;
> - int i, j;
> + struct dict_iterator iter;
> + int j;
>
> ALL_SYMTABS (objfile, s)
> {
> @@ -3448,10 +3450,10 @@ symtab_for_sym (struct symbol *sym)
> case LOC_BLOCK:
> case LOC_CONST_BYTES:
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, tmp_sym) if (sym == tmp_sym)
> + ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
> return s;
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, tmp_sym) if (sym == tmp_sym)
> + ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
> return s;
> break;
> default:
> @@ -3475,7 +3477,7 @@ symtab_for_sym (struct symbol *sym)
> j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
> {
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
> - ALL_BLOCK_SYMBOLS (b, i, tmp_sym) if (sym == tmp_sym)
> + ALL_BLOCK_SYMBOLS (b, iter, tmp_sym) if (sym == tmp_sym)
> return s;
> }
> break;
> @@ -3948,13 +3950,12 @@ ada_add_block_symbols (struct block *blo
> namespace_enum namespace, struct objfile *objfile,
> int wild)
> {
> - int i;
> + struct dict_iterator iter;
> int name_len = strlen (name);
> /* A matching argument symbol, if any. */
> struct symbol *arg_sym;
> /* Set true when we find a matching non-argument symbol */
> int found_sym;
> - int is_sorted = BLOCK_SHOULD_SORT (block);
> struct symbol *sym;
>
> arg_sym = NULL;
> @@ -3962,7 +3963,7 @@ ada_add_block_symbols (struct block *blo
> if (wild)
> {
> struct symbol *sym;
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> if (SYMBOL_NAMESPACE (sym) == namespace &&
> wild_match (name, name_len, DEPRECATED_SYMBOL_NAME (sym)))
> @@ -3991,45 +3992,15 @@ ada_add_block_symbols (struct block *blo
> }
> else
> {
> - if (is_sorted)
> - {
> - int U;
> - i = 0;
> - U = BLOCK_NSYMS (block) - 1;
> - while (U - i > 4)
> - {
> - int M = (U + i) >> 1;
> - struct symbol *sym = BLOCK_SYM (block, M);
> - if (DEPRECATED_SYMBOL_NAME (sym)[0] < name[0])
> - i = M + 1;
> - else if (DEPRECATED_SYMBOL_NAME (sym)[0] > name[0])
> - U = M - 1;
> - else if (strcmp (DEPRECATED_SYMBOL_NAME (sym), name) < 0)
> - i = M + 1;
> - else
> - U = M;
> - }
> - }
> - else
> - i = 0;
> -
> - for (; i < BLOCK_BUCKETS (block); i += 1)
> - for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> if (SYMBOL_NAMESPACE (sym) == namespace)
> {
> int cmp = strncmp (name, DEPRECATED_SYMBOL_NAME (sym), name_len);
>
> - if (cmp < 0)
> - {
> - if (is_sorted)
> - {
> - i = BLOCK_BUCKETS (block);
> - break;
> - }
> - }
> - else if (cmp == 0
> - && is_name_suffix (DEPRECATED_SYMBOL_NAME (sym) + name_len))
> +
> + if (cmp == 0
> + && is_name_suffix (DEPRECATED_SYMBOL_NAME (sym) + name_len))
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -4066,33 +4037,9 @@ ada_add_block_symbols (struct block *blo
> {
> arg_sym = NULL;
> found_sym = 0;
> - if (is_sorted)
> - {
> - int U;
> - i = 0;
> - U = BLOCK_NSYMS (block) - 1;
> - while (U - i > 4)
> - {
> - int M = (U + i) >> 1;
> - struct symbol *sym = BLOCK_SYM (block, M);
> - if (DEPRECATED_SYMBOL_NAME (sym)[0] < '_')
> - i = M + 1;
> - else if (DEPRECATED_SYMBOL_NAME (sym)[0] > '_')
> - U = M - 1;
> - else if (strcmp (DEPRECATED_SYMBOL_NAME (sym), "_ada_") < 0)
> - i = M + 1;
> - else
> - U = M;
> - }
> - }
> - else
> - i = 0;
>
> - for (; i < BLOCK_BUCKETS (block); i += 1)
> - for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> - struct symbol *sym = BLOCK_SYM (block, i);
> -
> if (SYMBOL_NAMESPACE (sym) == namespace)
> {
> int cmp;
> @@ -4105,16 +4052,8 @@ ada_add_block_symbols (struct block *blo
> cmp = strncmp (name, DEPRECATED_SYMBOL_NAME (sym) + 5, name_len);
> }
>
> - if (cmp < 0)
> - {
> - if (is_sorted)
> - {
> - i = BLOCK_BUCKETS (block);
> - break;
> - }
> - }
> - else if (cmp == 0
> - && is_name_suffix (DEPRECATED_SYMBOL_NAME (sym) + name_len + 5))
> + if (cmp == 0
> + && is_name_suffix (DEPRECATED_SYMBOL_NAME (sym) + name_len + 5))
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -4161,7 +4100,7 @@ fill_in_ada_prototype (struct symbol *fu
> {
> struct block *b;
> int nargs, nsyms;
> - int i;
> + struct dict_iterator iter;
> struct type *ftype;
> struct type *rtype;
> size_t max_fields;
> @@ -4187,7 +4126,7 @@ fill_in_ada_prototype (struct symbol *fu
> max_fields = 8;
> TYPE_FIELDS (ftype) =
> (struct field *) xmalloc (sizeof (struct field) * max_fields);
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs + 1);
>
> @@ -4760,8 +4699,8 @@ debug_print_lines (struct linetable *lt)
> static void
> debug_print_block (struct block *b)
> {
> - int i;
> - struct symbol *i;
> + struct dict_iterator iter;
> + struct symbol *sym;
>
> fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]",
> b, BLOCK_START (b), BLOCK_END (b));
> @@ -4770,10 +4709,8 @@ debug_print_block (struct block *b)
> fprintf (stderr, "\n");
> fprintf (stderr, "\t Superblock: %p\n", BLOCK_SUPERBLOCK (b));
> fprintf (stderr, "\t Symbols:");
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> - if (i > 0 && i % 4 == 0)
> - fprintf (stderr, "\n\t\t ");
> fprintf (stderr, " %s", DEPRECATED_SYMBOL_NAME (sym));
> }
> fprintf (stderr, "\n");
> Index: block.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/block.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 block.h
> --- block.h 15 Apr 2003 23:07:11 -0000 1.3
> +++ block.h 30 Apr 2003 22:45:38 -0000
> @@ -29,6 +29,7 @@ struct symtab;
> struct block_namespace_info;
> struct using_direct;
> struct obstack;
> +struct dictionary;
>
> /* All of the name-scope contours of the program
> are represented by `struct block' objects.
> @@ -77,6 +78,10 @@ struct block
>
> struct block *superblock;
>
> + /* This is used to store the symbols in the block. */
> +
> + struct dictionary *dict;
> +
> /* Used for language-specific info. */
>
> union
> @@ -104,34 +109,6 @@ struct block
> of this flag is undefined. */
>
> unsigned char gcc_compile_flag;
> -
> - /* The symbols for this block are either in a simple linear list or
> - in a simple hashtable. Blocks which correspond to a function
> - (which have a list of symbols corresponding to arguments) use
> - a linear list, as do some older symbol readers (currently only
> - mdebugread and dstread). Other blocks are hashed.
> -
> - The hashtable uses the same hash function as the minsym hashtables,
> - found in minsyms.c:minsym_hash_iw. Symbols are hashed based on
> - their demangled name if appropriate, and on their name otherwise.
> - The hash function ignores space, and stops at the beginning of the
> - argument list if any.
> -
> - The table is laid out in NSYMS/5 buckets and symbols are chained via
> - their hash_next field. */
> -
> - /* If this is really a hashtable of the symbols, this flag is 1. */
> -
> - unsigned char hashtable;
> -
> - /* Number of local symbols. */
> -
> - int nsyms;
> -
> - /* The symbols. If some of them are arguments, then they must be
> - in the order in which we would like to print them. */
> -
> - struct symbol *sym[1];
> };
>
> #define BLOCK_START(bl) (bl)->startaddr
> @@ -139,36 +116,15 @@ struct block
> #define BLOCK_FUNCTION(bl) (bl)->function
> #define BLOCK_SUPERBLOCK(bl) (bl)->superblock
> #define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
> +#define BLOCK_DICT(bl) (bl)->dict
> #define BLOCK_NAMESPACE(bl) (bl)->language_specific.cplus_specific.namespace
> -#define BLOCK_HASHTABLE(bl) (bl)->hashtable
>
> -/* For blocks without a hashtable (BLOCK_HASHTABLE (bl) == 0) only. */
> -#define BLOCK_NSYMS(bl) (bl)->nsyms
> -#define BLOCK_SYM(bl, n) (bl)->sym[n]
> -
> -/* For blocks with a hashtable, but these are valid for non-hashed blocks as
> - well - each symbol will appear to be one bucket by itself. */
> -#define BLOCK_BUCKETS(bl) (bl)->nsyms
> -#define BLOCK_BUCKET(bl, n) (bl)->sym[n]
> -
> -/* Macro used to set the size of a hashtable for N symbols. */
> -#define BLOCK_HASHTABLE_SIZE(n) ((n)/5 + 1)
> -
> -/* Macro to loop through all symbols in a block BL, in no particular order.
> - i counts which bucket we are in, and sym points to the current symbol. */
> -
> -#define ALL_BLOCK_SYMBOLS(bl, i, sym) \
> - for ((i) = 0; (i) < BLOCK_BUCKETS ((bl)); (i)++) \
> - for ((sym) = BLOCK_BUCKET ((bl), (i)); (sym); \
> - (sym) = (sym)->hash_next)
> -
> -/* Nonzero if symbols of block BL should be sorted alphabetically.
> - Don't sort a block which corresponds to a function. If we did the
> - sorting would have to preserve the order of the symbols for the
> - arguments. Also don't sort any block that we chose to hash. */
> +/* Macro to loop through all symbols in a block BL, in no particular
> + order. ITER helps keep track of the iteration, and should be a
> + struct dict_iterator. SYM points to the current symbol. */
>
> -#define BLOCK_SHOULD_SORT(bl) (! BLOCK_HASHTABLE (bl) \
> - && BLOCK_FUNCTION (bl) == NULL)
> +#define ALL_BLOCK_SYMBOLS(block, iter, sym) \
> + ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
>
> struct blockvector
> {
> Index: buildsym.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/buildsym.c,v
> retrieving revision 1.32
> diff -u -p -r1.32 buildsym.c
> --- buildsym.c 15 Apr 2003 23:07:11 -0000 1.32
> +++ buildsym.c 30 Apr 2003 22:45:39 -0000
> @@ -45,6 +45,7 @@
> #include "demangle.h" /* Needed by SYMBOL_INIT_DEMANGLED_NAME. */
> #include "block.h"
> #include "cp-support.h"
> +#include "dictionary.h"
>
> /* Ask buildsym.h to define the vars it normally declares `extern'. */
> #define EXTERN
> @@ -229,62 +230,22 @@ finish_block (struct symbol *symbol, str
> register struct block *block;
> register struct pending_block *pblock;
> struct pending_block *opblock;
> - register int i;
> - register int j;
> -
> - /* Count the length of the list of symbols. */
> -
> - for (next = *listhead, i = 0;
> - next;
> - i += next->nsyms, next = next->next)
> - {
> - /* EMPTY */ ;
> - }
>
> - /* Copy the symbols into the block. */
> + /* Initialize the block's dictionary. */
>
> if (symbol)
> {
> block = (struct block *)
> - obstack_alloc (&objfile->symbol_obstack,
> - (sizeof (struct block) +
> - ((i - 1) * sizeof (struct symbol *))));
> - BLOCK_NSYMS (block) = i;
> - for (next = *listhead; next; next = next->next)
> - for (j = next->nsyms - 1; j >= 0; j--)
> - {
> - BLOCK_SYM (block, --i) = next->symbol[j];
> - }
> + obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
> + BLOCK_DICT (block) = dict_create_linear (&objfile->symbol_obstack,
> + *listhead);
> }
> else
> {
> - int htab_size = BLOCK_HASHTABLE_SIZE (i);
> -
> block = (struct block *)
> - obstack_alloc (&objfile->symbol_obstack,
> - (sizeof (struct block) +
> - ((htab_size - 1) * sizeof (struct symbol *))));
> - for (j = 0; j < htab_size; j++)
> - {
> - BLOCK_BUCKET (block, j) = 0;
> - }
> - BLOCK_BUCKETS (block) = htab_size;
> - for (next = *listhead; next; next = next->next)
> - {
> - for (j = next->nsyms - 1; j >= 0; j--)
> - {
> - struct symbol *sym;
> - unsigned int hash_index;
> - const char *name = SYMBOL_DEMANGLED_NAME (next->symbol[j]);
> - if (name == NULL)
> - name = DEPRECATED_SYMBOL_NAME (next->symbol[j]);
> - hash_index = msymbol_hash_iw (name);
> - hash_index = hash_index % BLOCK_BUCKETS (block);
> - sym = BLOCK_BUCKET (block, hash_index);
> - BLOCK_BUCKET (block, hash_index) = next->symbol[j];
> - next->symbol[j]->hash_next = sym;
> - }
> - }
> + obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
> + BLOCK_DICT (block) = dict_create_hashed (&objfile->symbol_obstack,
> + *listhead);
> }
>
> BLOCK_START (block) = start;
> @@ -300,9 +261,9 @@ finish_block (struct symbol *symbol, str
> if (symbol)
> {
> struct type *ftype = SYMBOL_TYPE (symbol);
> + struct dict_iterator iter;
> SYMBOL_BLOCK_VALUE (symbol) = block;
> BLOCK_FUNCTION (block) = symbol;
> - BLOCK_HASHTABLE (block) = 0;
>
> if (TYPE_NFIELDS (ftype) <= 0)
> {
> @@ -311,7 +272,7 @@ finish_block (struct symbol *symbol, str
> parameter symbols. */
> int nparams = 0, iparams;
> struct symbol *sym;
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -348,9 +309,11 @@ finish_block (struct symbol *symbol, str
> TYPE_FIELDS (ftype) = (struct field *)
> TYPE_ALLOC (ftype, nparams * sizeof (struct field));
>
> - for (i = iparams = 0; iparams < nparams; i++)
> + for (sym = dict_iterator_first (BLOCK_DICT (block), &iter),
> + iparams = 0;
> + iparams < nparams;
> + sym = dict_iterator_next (&iter))

could you use the macro ALL_BLOCK_SYMBOLS here? and move the check for
iparams inside the loop body?

> {
> - sym = BLOCK_SYM (block, i);
> switch (SYMBOL_CLASS (sym))
> {
> case LOC_ARG:
> @@ -394,7 +357,6 @@ finish_block (struct symbol *symbol, str
> else
> {
> BLOCK_FUNCTION (block) = NULL;
> - BLOCK_HASHTABLE (block) = 1;
> }
>
> /* Now "free" the links of the list, and empty the list. */
> @@ -1031,7 +993,7 @@ end_symtab (CORE_ADDR end_addr, struct o
> symtab->dirname = NULL;
> }
> symtab->free_code = free_linetable;
> - symtab->free_ptr = NULL;
> + symtab->free_func = NULL;
>
> /* Use whatever language we have been using for this
> subfile, not the one that was deduced in allocate_symtab
> Index: coffread.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/coffread.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 coffread.c
> --- coffread.c 25 Feb 2003 21:36:17 -0000 1.37
> +++ coffread.c 30 Apr 2003 22:45:42 -0000
> @@ -45,6 +45,7 @@
> #include "target.h"
> #include "gdb_assert.h"
> #include "block.h"
> +#include "dictionary.h"
>
> #include "coff-pe-read.h"
>
> @@ -605,15 +606,6 @@ coff_symfile_read (struct objfile *objfi
>
> coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
>
> - /* Sort symbols alphabetically within each block. */
> -
> - {
> - struct symtab *s;
> -
> - for (s = objfile->symtabs; s != NULL; s = s->next)
> - sort_symtab_syms (s);
> - }
> -
> /* Install any minimal symbols that have been collected as the current
> minimal symbols for this objfile. */
>
> @@ -1413,12 +1405,12 @@ static void
> patch_opaque_types (struct symtab *s)
> {
> register struct block *b;
> - register int i;
> + struct dict_iterator iter;
> register struct symbol *real_sym;
>
> /* Go through the per-file symbols only */
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, real_sym)
> + ALL_BLOCK_SYMBOLS (b, iter, real_sym)
> {
> /* Find completed typedefs to use to fix opaque ones.
> Remove syms from the chain when their types are stored,
> Index: dbxread.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dbxread.c,v
> retrieving revision 1.45
> diff -u -p -r1.45 dbxread.c
> --- dbxread.c 26 Feb 2003 21:41:18 -0000 1.45
> +++ dbxread.c 30 Apr 2003 22:45:46 -0000
> @@ -2484,7 +2484,6 @@ dbx_psymtab_to_symtab_1 (struct partial_
> /* Read in this file's symbols */
> bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
> read_ofile_symtab (pst);
> - sort_symtab_syms (pst->symtab);
>
> do_cleanups (old_chain);
> }
> Index: dwarf2read.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarf2read.c,v
> retrieving revision 1.90
> diff -u -p -r1.90 dwarf2read.c
> --- dwarf2read.c 15 Apr 2003 23:07:11 -0000 1.90
> +++ dwarf2read.c 30 Apr 2003 22:45:53 -0000
> @@ -1740,7 +1740,6 @@ psymtab_to_symtab_1 (struct partial_symt
> }
> pst->symtab = symtab;
> pst->readin = 1;
> - sort_symtab_syms (pst->symtab);
>
> do_cleanups (back_to);
> }
> Index: dwarfread.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/dwarfread.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 dwarfread.c
> --- dwarfread.c 25 Feb 2003 21:36:17 -0000 1.24
> +++ dwarfread.c 30 Apr 2003 22:45:57 -0000
> @@ -2338,7 +2338,6 @@ psymtab_to_symtab_1 (struct partial_symt
> wrap_here ("");
> gdb_flush (gdb_stdout);
> }
> - sort_symtab_syms (pst->symtab);
> do_cleanups (old_chain);
> }
> pst->readin = 1;
> Index: jv-lang.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/jv-lang.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 jv-lang.c
> --- jv-lang.c 15 Apr 2003 23:07:11 -0000 1.18
> +++ jv-lang.c 30 Apr 2003 22:45:58 -0000
> @@ -35,6 +35,7 @@
> #include "gdbcore.h"
> #include "block.h"
> #include "demangle.h"
> +#include "dictionary.h"
> #include <ctype.h>
>
> struct type *java_int_type;
> @@ -91,9 +92,7 @@ get_dynamics_objfile (void)
>
> static struct symtab *class_symtab = NULL;
>
> -/* Maximum number of class in class_symtab before relocation is needed. */
> -
> -static int class_symtab_space;
> +static void free_class_block (struct symtab *symtab);
>
> static struct symtab *
> get_java_class_symtab (void)
> @@ -106,15 +105,16 @@ get_java_class_symtab (void)
> class_symtab = allocate_symtab ("<java-classes>", objfile);
> class_symtab->language = language_java;
> bv = (struct blockvector *)
> - obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector));
> + obstack_alloc (&objfile->symbol_obstack,
> + sizeof (struct blockvector) + sizeof (struct block *));
> BLOCKVECTOR_NBLOCKS (bv) = 1;
> BLOCKVECTOR (class_symtab) = bv;
>
> /* Allocate dummy STATIC_BLOCK. */
> bl = (struct block *)
> obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
> - BLOCK_NSYMS (bl) = 0;
> - BLOCK_HASHTABLE (bl) = 0;
> + BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
> + NULL);
> BLOCK_START (bl) = 0;
> BLOCK_END (bl) = 0;
> BLOCK_FUNCTION (bl) = NULL;
> @@ -124,13 +124,12 @@ get_java_class_symtab (void)
> BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
>
> /* Allocate GLOBAL_BLOCK. This has to be relocatable. */
> - class_symtab_space = 128;
> - bl = xmmalloc (objfile->md,
> - sizeof (struct block)
> - + ((class_symtab_space - 1) * sizeof (struct symbol *)));
> + bl = (struct block *)
> + obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
> *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
> + BLOCK_DICT (bl) = dict_create_hashed_expandable ();
> BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
> - class_symtab->free_ptr = (char *) bl;
> + class_symtab->free_func = free_class_block;
> }
> return class_symtab;
> }
> @@ -140,20 +139,7 @@ add_class_symtab_symbol (struct symbol *
> {
> struct symtab *symtab = get_java_class_symtab ();
> struct blockvector *bv = BLOCKVECTOR (symtab);
> - struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
> - if (BLOCK_NSYMS (bl) >= class_symtab_space)
> - {
> - /* Need to re-allocate. */
> - class_symtab_space *= 2;
> - bl = xmrealloc (symtab->objfile->md, bl,
> - sizeof (struct block)
> - + ((class_symtab_space - 1) * sizeof (struct symbol *)));
> - class_symtab->free_ptr = (char *) bl;
> - BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
> - }
> -
> - BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym;
> - BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1;
> + dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym);
> }
>
> static struct symbol *add_class_symbol (struct type *type, CORE_ADDR addr);
> @@ -174,6 +160,16 @@ add_class_symbol (struct type *type, COR
> SYMBOL_VALUE_ADDRESS (sym) = addr;
> return sym;
> }
> +
> +/* Free the dynamic symbols block. */
> +static void
> +free_class_block (struct symtab *symtab)
> +{
> + struct blockvector *bv = BLOCKVECTOR (symtab);
> + struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
> +
> + dict_free (BLOCK_DICT (bl));
> +}
> #endif
>
> struct type *
> @@ -268,7 +264,7 @@ type_from_class (struct value *clas)
> char *nptr;
> CORE_ADDR addr;
> struct block *bl;
> - int i;
> + struct dict_iterator iter;
> int is_array = 0;
>
> type = check_typedef (VALUE_TYPE (clas));
> @@ -283,9 +279,8 @@ type_from_class (struct value *clas)
> #if 0
> get_java_class_symtab ();
> bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
> - for (i = BLOCK_NSYMS (bl); --i >= 0;)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> - struct symbol *sym = BLOCK_SYM (bl, i);
> if (SYMBOL_VALUE_ADDRESS (sym) == addr)
> return SYMBOL_TYPE (sym);
> }
> Index: mdebugread.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/mdebugread.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 mdebugread.c
> --- mdebugread.c 19 Mar 2003 19:45:49 -0000 1.44
> +++ mdebugread.c 30 Apr 2003 22:46:03 -0000
> @@ -54,6 +54,7 @@
> #include "demangle.h"
> #include "gdb_assert.h"
> #include "block.h"
> +#include "dictionary.h"
>
> /* These are needed if the tm.h file does not contain the necessary
> mips specific definitions. */
> @@ -284,9 +285,9 @@ static struct symbol *new_symbol (char *
>
> static struct type *new_type (char *);
>
> -static struct block *new_block (int);
> +static struct block *new_block (int function);

can this take an enum parameter with some meaningful names?

>
> -static struct symtab *new_symtab (char *, int, int, struct objfile *);
> +static struct symtab *new_symtab (char *, int, struct objfile *);
>
> static struct linetable *new_linetable (int);
>
> @@ -298,8 +299,6 @@ static struct type *parse_type (int, uni
> static struct symbol *mylookup_symbol (char *, struct block *, namespace_enum,
> enum address_class);
>
> -static struct block *shrink_block (struct block *, struct symtab *);
> -
> static void sort_blocks (struct symtab *);
>
> static struct partial_symtab *new_psymtab (char *, struct objfile *);
> @@ -483,7 +482,6 @@ static struct parse_stack
>
> int blocktype;
>
> - int maxsyms; /* Max symbols in this block. */
> struct type *cur_type; /* Type we parse fields for. */
> int cur_field; /* Field number in cur_type. */
> CORE_ADDR procadr; /* Start addres of this procedure */
> @@ -834,7 +832,7 @@ parse_symbol (SYMR *sh, union aux_ext *a
> TYPE_FLAGS (SYMBOL_TYPE (s)) |= TYPE_FLAG_PROTOTYPED;
>
> /* Create and enter a new lexical context */
> - b = new_block (top_stack->maxsyms);
> + b = new_block (1);
> SYMBOL_BLOCK_VALUE (s) = b;
> BLOCK_FUNCTION (b) = s;
> BLOCK_START (b) = BLOCK_END (b) = sh->value;
> @@ -1169,7 +1167,7 @@ parse_symbol (SYMR *sh, union aux_ext *a
> }
>
> top_stack->blocktype = stBlock;
> - b = new_block (top_stack->maxsyms);
> + b = new_block (0);
> BLOCK_START (b) = sh->value + top_stack->procadr;
> BLOCK_SUPERBLOCK (b) = top_stack->cur_block;
> top_stack->cur_block = b;
> @@ -1189,7 +1187,7 @@ parse_symbol (SYMR *sh, union aux_ext *a
> /* Finished with procedure */
> struct blockvector *bv = BLOCKVECTOR (top_stack->cur_st);
> struct mips_extra_func_info *e;
> - struct block *b;
> + struct block *b = top_stack->cur_block;
> struct type *ftype = top_stack->cur_type;
> int i;
>
> @@ -1209,9 +1207,6 @@ parse_symbol (SYMR *sh, union aux_ext *a
> e->pdr.framereg = -1;
> add_symbol (s, top_stack->cur_block);
>
> - /* Reallocate symbols, saving memory */
> - b = shrink_block (top_stack->cur_block, top_stack->cur_st);
> -
> /* f77 emits proc-level with address bounds==[0,0],
> So look for such child blocks, and patch them. */
> for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++)
> @@ -1236,13 +1231,16 @@ parse_symbol (SYMR *sh, union aux_ext *a
>
> if (nparams > 0)
> {
> + struct dict_iterator iter;
> TYPE_NFIELDS (ftype) = nparams;
> TYPE_FIELDS (ftype) = (struct field *)
> TYPE_ALLOC (ftype, nparams * sizeof (struct field));
>
> - for (i = iparams = 0; iparams < nparams; i++)
> + for (sym = dict_iterator_first (BLOCK_DICT (b), &iter),
> + iparams = 0;
> + iparams < nparams;
> + sym = dict_iterator_next (&iter))

could you still use the macro here ALL_BLOCK_SYMBOLS and add an if
(iparams == nparams) break; inside the loop?

> {
> - sym = BLOCK_SYM (b, i);
> switch (SYMBOL_CLASS (sym))
> {
> case LOC_ARG:
> @@ -1266,7 +1264,6 @@ parse_symbol (SYMR *sh, union aux_ext *a
> displacement from the procedure`s start address of the
> end of this block. */
> BLOCK_END (top_stack->cur_block) = sh->value + top_stack->procadr;
> - shrink_block (top_stack->cur_block, top_stack->cur_st);
> }
> else if (sh->sc == scText && top_stack->blocktype == stNil)
> {
> @@ -4008,10 +4005,6 @@ psymtab_to_symtab_1 (struct partial_symt
> end_stabs ();
> }
>
> - /* Sort the symbol table now, we are done adding symbols to it.
> - We must do this before parse_procedure calls lookup_symbol. */
> - sort_symtab_syms (st);
> -
> /* There used to be a call to sort_blocks here, but this should not
> be necessary for stabs symtabs. And as sort_blocks modifies the
> start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK,
> @@ -4065,19 +4058,15 @@ psymtab_to_symtab_1 (struct partial_symt
> int maxlines;
> EXTR *ext_ptr;
>
> - /* How many symbols will we need */
> - /* FIXME, this does not count enum values. */
> - f_max = pst->n_global_syms + pst->n_static_syms;
> if (fh == 0)
> {
> maxlines = 0;
> - st = new_symtab ("unknown", f_max, 0, pst->objfile);
> + st = new_symtab ("unknown", 0, pst->objfile);
> }
> else
> {
> - f_max += fh->csym + fh->cpd;
> maxlines = 2 * fh->cline;
> - st = new_symtab (pst->filename, 2 * f_max, maxlines, pst->objfile);
> + st = new_symtab (pst->filename, maxlines, pst->objfile);
>
> /* The proper language was already determined when building
> the psymtab, use it. */
> @@ -4097,7 +4086,6 @@ psymtab_to_symtab_1 (struct partial_symt
> BLOCK_START (top_stack->cur_block) = pst->textlow;
> BLOCK_END (top_stack->cur_block) = 0;
> top_stack->blocktype = stFile;
> - top_stack->maxsyms = 2 * f_max;
> top_stack->cur_type = 0;
> top_stack->procadr = 0;
> top_stack->numargs = 0;
> @@ -4181,10 +4169,6 @@ psymtab_to_symtab_1 (struct partial_symt
> top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (top_stack->cur_st),
> GLOBAL_BLOCK);
> top_stack->blocktype = stFile;
> - top_stack->maxsyms
> - = (debug_info->symbolic_header.isymMax
> - + debug_info->symbolic_header.ipdMax
> - + debug_info->symbolic_header.iextMax);
>
> ext_ptr = PST_PRIVATE (pst)->extern_tab;
> for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
> @@ -4206,9 +4190,6 @@ psymtab_to_symtab_1 (struct partial_symt
>
> st->primary = 1;
>
> - /* Sort the symbol table now, we are done adding symbols to it. */
> - sort_symtab_syms (st);
> -
> sort_blocks (st);
> }
>
> @@ -4457,11 +4438,12 @@ static struct symbol *
> mylookup_symbol (char *name, register struct block *block,
> namespace_enum namespace, enum address_class class)
> {
> - int i, inc;
> + struct dict_iterator iter;
> + int inc;
> struct symbol *sym;
>
> inc = name[0];
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> if (DEPRECATED_SYMBOL_NAME (sym)[0] == inc
> && SYMBOL_NAMESPACE (sym) == namespace
> @@ -4477,41 +4459,12 @@ mylookup_symbol (char *name, register st
> }
>
>
> -/* Add a new symbol S to a block B.
> - Infrequently, we will need to reallocate the block to make it bigger.
> - We only detect this case when adding to top_stack->cur_block, since
> - that's the only time we know how big the block is. FIXME. */
> +/* Add a new symbol S to a block B. */
>
> static void
> add_symbol (struct symbol *s, struct block *b)
> {
> - int nsyms = BLOCK_NSYMS (b)++;
> - struct block *origb;
> - struct parse_stack *stackp;
> -
> - if (b == top_stack->cur_block &&
> - nsyms >= top_stack->maxsyms)
> - {
> - complaint (&symfile_complaints, "block containing %s overfilled",
> - DEPRECATED_SYMBOL_NAME (s));
> - /* In this case shrink_block is actually grow_block, since
> - BLOCK_NSYMS(b) is larger than its current size. */
> - origb = b;
> - b = shrink_block (top_stack->cur_block, top_stack->cur_st);
> -
> - /* Now run through the stack replacing pointers to the
> - original block. shrink_block has already done this
> - for the blockvector and BLOCK_FUNCTION. */
> - for (stackp = top_stack; stackp; stackp = stackp->next)
> - {
> - if (stackp->cur_block == origb)
> - {
> - stackp->cur_block = b;
> - stackp->maxsyms = BLOCK_NSYMS (b);
> - }
> - }
> - }
> - BLOCK_SYM (b, nsyms) = s;
> + dict_add_symbol (BLOCK_DICT (b), s);
> }
>
> /* Add a new block B to a symtab S */
> @@ -4633,11 +4586,11 @@ sort_blocks (struct symtab *s)
>
> /* Constructor/restructor/destructor procedures */
>
> -/* Allocate a new symtab for NAME. Needs an estimate of how many symbols
> - MAXSYMS and linenumbers MAXLINES we'll put in it */
> +/* Allocate a new symtab for NAME. Needs an estimate of how many
> + linenumbers MAXLINES we'll put in it */
>
> static struct symtab *
> -new_symtab (char *name, int maxsyms, int maxlines, struct objfile *objfile)
> +new_symtab (char *name, int maxlines, struct objfile *objfile)
> {
> struct symtab *s = allocate_symtab (name, objfile);
>
> @@ -4645,8 +4598,8 @@ new_symtab (char *name, int maxsyms, int
>
> /* All symtabs must have at least two blocks */
> BLOCKVECTOR (s) = new_bvect (2);
> - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) = new_block (maxsyms);
> - BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) = new_block (maxsyms);
> + BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK) = new_block (0);
> + BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK) = new_block (0);
> BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)) =
> BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
>
> @@ -4730,48 +4683,22 @@ new_bvect (int nblocks)
> return bv;
> }
>
> -/* Allocate and zero a new block of MAXSYMS symbols */
> +/* Allocate and zero a new block, and set its BLOCK_DICT. If function
> + is non-zero, assume the block is associated to a function, and make
> + sure that the symbols are stored linearly; otherwise, store them
> + hashed. */
>
> static struct block *
> -new_block (int maxsyms)
> +new_block (int function)
> {
> - int size = sizeof (struct block) + (maxsyms - 1) * sizeof (struct symbol *);
> + struct block *retval = xzalloc (sizeof (struct block));
>
> - return (struct block *) xzalloc (size);
> -}
> -
> -/* Ooops, too big. Shrink block B in symtab S to its minimal size.
> - Shrink_block can also be used by add_symbol to grow a block. */
> -
> -static struct block *
> -shrink_block (struct block *b, struct symtab *s)
> -{
> - struct block *new;
> - struct blockvector *bv = BLOCKVECTOR (s);
> - int i;
> -
> - /* Just reallocate it and fix references to the old one */
> + if (function)
> + BLOCK_DICT (retval) = dict_create_linear_expandable ();
> + else
> + BLOCK_DICT (retval) = dict_create_hashed_expandable ();
>
> - new = (struct block *) xrealloc ((void *) b,
> - (sizeof (struct block)
> - + ((BLOCK_NSYMS (b) - 1)
> - * sizeof (struct symbol *))));
> -
> - /* FIXME: Not worth hashing this block as it's built. */
> - /* All callers should have created the block with new_block (), which
> - would mean it was not previously hashed. Make sure. */
> - gdb_assert (BLOCK_HASHTABLE (new) == 0);
> -
> - /* Should chase pointers to old one. Fortunately, that`s just
> - the block`s function and inferior blocks */
> - if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b)
> - SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) = new;
> - for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); i++)
> - if (BLOCKVECTOR_BLOCK (bv, i) == b)
> - BLOCKVECTOR_BLOCK (bv, i) = new;
> - else if (BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) == b)
> - BLOCK_SUPERBLOCK (BLOCKVECTOR_BLOCK (bv, i)) = new;
> - return new;
> + return retval;
> }
>
> /* Create a new symbol with printname NAME */
> @@ -4908,7 +4835,7 @@ fixup_sigtramp (void)
> TYPE_TARGET_TYPE (SYMBOL_TYPE (s)) = mdebug_type_void;
>
> /* Need a block to allocate MIPS_EFI_SYMBOL_NAME in */
> - b = new_block (1);
> + b = new_block (0);
> SYMBOL_BLOCK_VALUE (s) = b;
> BLOCK_START (b) = sigtramp_address;
> BLOCK_END (b) = sigtramp_end;
> @@ -4951,7 +4878,7 @@ fixup_sigtramp (void)
> current_objfile = NULL;
> }
>
> - BLOCK_SYM (b, BLOCK_NSYMS (b)++) = s;
> + dict_add_symbol (BLOCK_DICT (b), s);
> }
>
> #endif /* TM_MIPS_H */
> Index: objfiles.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/objfiles.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 objfiles.c
> --- objfiles.c 25 Feb 2003 21:36:18 -0000 1.29
> +++ objfiles.c 30 Apr 2003 22:46:05 -0000
> @@ -43,6 +43,7 @@
>
> #include "breakpoint.h"
> #include "block.h"
> +#include "dictionary.h"
>
> /* Prototypes for local functions */
>
> @@ -656,13 +657,13 @@ objfile_relocate (struct objfile *objfil
> {
> struct block *b;
> struct symbol *sym;
> - int j;
> + struct dict_iterator iter;
>
> b = BLOCKVECTOR_BLOCK (bv, i);
> BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
> BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
>
> - ALL_BLOCK_SYMBOLS (b, j, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> fixup_symbol_section (sym, objfile);
>
> Index: printcmd.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/printcmd.c,v
> retrieving revision 1.59
> diff -u -p -r1.59 printcmd.c
> --- printcmd.c 1 Apr 2003 23:51:17 -0000 1.59
> +++ printcmd.c 30 Apr 2003 22:46:07 -0000
> @@ -42,6 +42,7 @@
> #include "ui-out.h"
> #include "gdb_assert.h"
> #include "block.h"
> +#include "dictionary.h"
>
> extern int asm_demangle; /* Whether to demangle syms in asm printouts */
> extern int addressprint; /* Whether to print hex addresses in HLL " */
> @@ -1760,7 +1761,7 @@ print_frame_args (struct symbol *func, s
> {
> struct block *b = NULL;
> int first = 1;
> - register int i;
> + struct dict_iterator iter;
> register struct symbol *sym;
> struct value *val;
> /* Offset of next stack argument beyond the one we have seen that is
> @@ -1779,11 +1780,8 @@ print_frame_args (struct symbol *func, s
> if (func)
> {
> b = SYMBOL_BLOCK_VALUE (func);
> - /* Function blocks are order sensitive, and thus should not be
> - hashed. */
> - gdb_assert (BLOCK_HASHTABLE (b) == 0);
>
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> QUIT;
>
> Index: stack.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/stack.c,v
> retrieving revision 1.73
> diff -u -p -r1.73 stack.c
> --- stack.c 5 Apr 2003 15:19:12 -0000 1.73
> +++ stack.c 30 Apr 2003 22:46:09 -0000
> @@ -40,6 +40,7 @@
> #include "annotate.h"
> #include "ui-out.h"
> #include "block.h"
> +#include "dictionary.h"
>
> /* Prototypes for exported functions. */
>
> @@ -1061,11 +1062,12 @@ static int
> print_block_frame_locals (struct block *b, register struct frame_info *fi,
> int num_tabs, register struct ui_file *stream)
> {
> - register int i, j;
> + struct dict_iterator iter;
> + register int j;

no need for register.

> register struct symbol *sym;
> register int values_printed = 0;
>
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -1097,11 +1099,11 @@ static int
> print_block_frame_labels (struct block *b, int *have_default,
> register struct ui_file *stream)
> {
> - register int i;
> + struct dict_iterator iter;
> register struct symbol *sym;
> register int values_printed = 0;
>
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> if (STREQ (DEPRECATED_SYMBOL_NAME (sym), "default"))
> {
> @@ -1279,7 +1281,7 @@ print_frame_arg_vars (register struct fr
> {
> struct symbol *func = get_frame_function (fi);
> register struct block *b;
> - register int i;
> + struct dict_iterator iter;
> register struct symbol *sym, *sym2;
> register int values_printed = 0;
>
> @@ -1290,7 +1292,7 @@ print_frame_arg_vars (register struct fr
> }
>
> b = SYMBOL_BLOCK_VALUE (func);
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> Index: symfile.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/symfile.c,v
> retrieving revision 1.93
> diff -u -p -r1.93 symfile.c
> --- symfile.c 1 Apr 2003 14:17:20 -0000 1.93
> +++ symfile.c 30 Apr 2003 22:46:13 -0000
> @@ -236,38 +236,6 @@ sort_pst_symbols (struct partial_symtab
> compare_psymbols);
> }
>
> -/* Call sort_block_syms to sort alphabetically the symbols of one block. */
> -
> -void
> -sort_block_syms (register struct block *b)
> -{
> - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
> - sizeof (struct symbol *), compare_symbols);
> -}
> -
> -/* Call sort_symtab_syms to sort alphabetically
> - the symbols of each block of one symtab. */
> -
> -void
> -sort_symtab_syms (register struct symtab *s)
> -{
> - register struct blockvector *bv;
> - int nbl;
> - int i;
> - register struct block *b;
> -
> - if (s == 0)
> - return;
> - bv = BLOCKVECTOR (s);
> - nbl = BLOCKVECTOR_NBLOCKS (bv);
> - for (i = 0; i < nbl; i++)
> - {
> - b = BLOCKVECTOR_BLOCK (bv, i);
> - if (BLOCK_SHOULD_SORT (b))
> - sort_block_syms (b);
> - }
> -}
> -
> /* Make a null terminated copy of the string at PTR with SIZE characters in
> the obstack pointed to by OBSTACKP . Returns the address of the copy.
> Note that the string at PTR does not have to be null terminated, I.E. it
> Index: symfile.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/symfile.h,v
> retrieving revision 1.20
> diff -u -p -r1.20 symfile.h
> --- symfile.h 12 Apr 2003 17:41:26 -0000 1.20
> +++ symfile.h 30 Apr 2003 22:46:13 -0000
> @@ -204,12 +204,6 @@ extern struct partial_symtab *start_psym
> struct partial_symbol **,
> struct partial_symbol **);
>
> -/* Sorting your symbols for fast lookup or alphabetical printing. */
> -
> -extern void sort_block_syms (struct block *);
> -
> -extern void sort_symtab_syms (struct symtab *);
> -
> /* Make a copy of the string at PTR with SIZE characters in the symbol obstack
> (and add a null character at the end in the copy).
> Returns the address of the copy. */
> Index: symmisc.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/symmisc.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 symmisc.c
> --- symmisc.c 14 Apr 2003 18:42:27 -0000 1.20
> +++ symmisc.c 30 Apr 2003 22:46:15 -0000
> @@ -34,6 +34,7 @@
> #include "bcache.h"
> #include "block.h"
> #include "gdb_regex.h"
> +#include "dictionary.h"
>
> #include "gdb_string.h"
> #include <readline/readline.h>
> @@ -87,22 +88,22 @@ static void free_symtab_block (struct ob
>
> /* Free a struct block <- B and all the symbols defined in that block. */
>
> +/* FIXME: carlton/2003-04-28: I don't believe this is currently ever
> + used. */
> +
> static void
> free_symtab_block (struct objfile *objfile, struct block *b)
> {
> - register int i, n;
> - struct symbol *sym, *next_sym;
> + struct dict_iterator iter;
> + struct symbol *sym;
>
> - n = BLOCK_BUCKETS (b);
> - for (i = 0; i < n; i++)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> - for (sym = BLOCK_BUCKET (b, i); sym; sym = next_sym)
> - {
> - next_sym = sym->hash_next;
> - xmfree (objfile->md, DEPRECATED_SYMBOL_NAME (sym));
> - xmfree (objfile->md, sym);
> - }
> + xmfree (objfile->md, DEPRECATED_SYMBOL_NAME (sym));
> + xmfree (objfile->md, sym);
> }
> +
> + dict_free (BLOCK_DICT (b));
> xmfree (objfile->md, b);
> }
>
> @@ -141,7 +142,7 @@ free_symtab (register struct symtab *s)
> /* Also free the linetable. */
>
> case free_linetable:
> - /* Everything will be freed either by our `free_ptr'
> + /* Everything will be freed either by our `free_func'
> or by some other symtab, except for our linetable.
> Free that now. */
> if (LINETABLE (s))
> @@ -150,8 +151,8 @@ free_symtab (register struct symtab *s)
> }
>
> /* If there is a single block of memory to free, free it. */
> - if (s->free_ptr != NULL)
> - xmfree (s->objfile->md, s->free_ptr);
> + if (s->free_func != NULL)
> + s->free_func (s);
>
> /* Free source-related stuff */
> if (s->line_charpos != NULL)
> @@ -444,7 +445,8 @@ static void
> dump_symtab (struct objfile *objfile, struct symtab *symtab,
> struct ui_file *outfile)
> {
> - register int i, j;
> + register int i;

no need for register.

> + struct dict_iterator iter;
> int len, blen;
> register struct linetable *l;
> struct blockvector *bv;
> @@ -493,6 +495,11 @@ dump_symtab (struct objfile *objfile, st
> fprintf_filtered (outfile, " under ");
> gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile);
> }
> +#if 0
> + /* NOTE: carlton/2003-04-28: If we really want to be able to
> + print out something here, we'll need to add an extra
> + dictionary method just for that purpose. */
> +

Hmmm, I think we should. We don't want to change gdb's behavior.

> /* drow/2002-07-10: We could save the total symbols count
> even if we're using a hashtable, but nothing else but this message
> wants it. */
> @@ -501,6 +508,7 @@ dump_symtab (struct objfile *objfile, st
> fprintf_filtered (outfile, ", %d buckets in ", blen);
> else
> fprintf_filtered (outfile, ", %d syms in ", blen);
> +#endif
> print_address_numeric (BLOCK_START (b), 1, outfile);
> fprintf_filtered (outfile, "..");
> print_address_numeric (BLOCK_END (b), 1, outfile);
> @@ -518,7 +526,7 @@ dump_symtab (struct objfile *objfile, st
> fprintf_filtered (outfile, "\n");
> /* Now print each symbol in this block (in no particular order, if
> we're using a hashtable). */
> - ALL_BLOCK_SYMBOLS (b, j, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> struct print_symbol_args s;
> s.symbol = sym;
> Index: symtab.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/symtab.c,v
> retrieving revision 1.101
> diff -u -p -r1.101 symtab.c
> --- symtab.c 14 Apr 2003 19:56:32 -0000 1.101
> +++ symtab.c 30 Apr 2003 22:46:19 -0000
> @@ -45,6 +45,7 @@
>
> #include "gdb_obstack.h"
> #include "block.h"
> +#include "dictionary.h"
>
> #include <sys/types.h>
> #include <fcntl.h>
> @@ -1666,127 +1667,40 @@ lookup_block_symbol (register const stru
> const char *mangled_name,
> const namespace_enum namespace)
> {
> - register int bot, top, inc;
> - register struct symbol *sym;
> - register struct symbol *sym_found = NULL;
> - register int do_linear_search = 1;
> + struct dict_iterator iter;
> + struct symbol *sym;
>
> - if (BLOCK_HASHTABLE (block))
> + if (!BLOCK_FUNCTION (block))
> {
> - unsigned int hash_index;
> - hash_index = msymbol_hash_iw (name);
> - hash_index = hash_index % BLOCK_BUCKETS (block);
> - for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
> - {
> - if (SYMBOL_NAMESPACE (sym) == namespace
> - && (mangled_name
> - ? strcmp (DEPRECATED_SYMBOL_NAME (sym), mangled_name) == 0
> - : SYMBOL_MATCHES_NATURAL_NAME (sym, name)))
> + for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
> + sym != NULL;
> + sym = dict_iter_name_next (name, &iter))
> + {
> + if (SYMBOL_NAMESPACE (sym) == namespace
> + && (mangled_name != NULL
> + ? strcmp (SYMBOL_LINKAGE_NAME (sym), mangled_name) == 0 : 1))
> return sym;
> }
> return NULL;
> }
> -
> - /* If the blocks's symbols were sorted, start with a binary search. */
> -
> - if (BLOCK_SHOULD_SORT (block))
> + else
> {
> - /* Reset the linear search flag so if the binary search fails, we
> - won't do the linear search once unless we find some reason to
> - do so */
> -
> - do_linear_search = 0;
> - top = BLOCK_NSYMS (block);
> - bot = 0;
> -
> - /* Advance BOT to not far before the first symbol whose name is NAME. */
> -
> - while (1)
> + /* Note that parameter symbols do not always show up last in the
> + list. This loop makes sure to take anything else other than
> + parameter symbols first; it only uses parameter symbols as a
> + last resort. Note that this only takes up extra computation
> + time on a match. */
> +
> + struct symbol *sym_found = NULL;
> +
> + for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
> + sym != NULL;
> + sym = dict_iter_name_next (name, &iter))
> {
> - inc = (top - bot + 1);
> - /* No need to keep binary searching for the last few bits worth. */
> - if (inc < 4)
> - {
> - break;
> - }
> - inc = (inc >> 1) + bot;
> - sym = BLOCK_SYM (block, inc);
> - if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
> - {
> - do_linear_search = 1;
> - }
> - if (SYMBOL_NATURAL_NAME (sym)[0] < name[0])
> - {
> - bot = inc;
> - }
> - else if (SYMBOL_NATURAL_NAME (sym)[0] > name[0])
> - {
> - top = inc;
> - }
> - else if (strcmp (SYMBOL_NATURAL_NAME (sym), name) < 0)
> - {
> - bot = inc;
> - }
> - else
> - {
> - top = inc;
> - }
> - }
> -
> - /* Now scan forward until we run out of symbols, find one whose
> - name is greater than NAME, or find one we want. If there is
> - more than one symbol with the right name and namespace, we
> - return the first one; I believe it is now impossible for us
> - to encounter two symbols with the same name and namespace
> - here, because blocks containing argument symbols are no
> - longer sorted. The exception is for C++, where multiple functions
> - (cloned constructors / destructors, in particular) can have
> - the same demangled name. So if we have a particular
> - mangled name to match, try to do so. */
> -
> - top = BLOCK_NSYMS (block);
> - while (bot < top)
> - {
> - sym = BLOCK_SYM (block, bot);
> if (SYMBOL_NAMESPACE (sym) == namespace
> - && (mangled_name
> - ? strcmp (DEPRECATED_SYMBOL_NAME (sym), mangled_name) == 0
> - : SYMBOL_MATCHES_NATURAL_NAME (sym, name)))
> - {
> - return sym;
> - }
> - if (SYMBOL_PRINT_NAME (sym)[0] > name[0])
> - {
> - break;
> - }
> - bot++;
> - }
> - }
> -
> - /* Here if block isn't sorted, or we fail to find a match during the
> - binary search above. If during the binary search above, we find a
> - symbol which is a Java symbol, then we have re-enabled the linear
> - search flag which was reset when starting the binary search.
> -
> - This loop is equivalent to the loop above, but hacked greatly for speed.
> -
> - Note that parameter symbols do not always show up last in the
> - list; this loop makes sure to take anything else other than
> - parameter symbols first; it only uses parameter symbols as a
> - last resort. Note that this only takes up extra computation
> - time on a match. */
> + && (mangled_name != NULL
> + ? strcmp (SYMBOL_LINKAGE_NAME (sym), mangled_name) == 0 : 1))
>
> - if (do_linear_search)
> - {
> - top = BLOCK_NSYMS (block);
> - bot = 0;
> - while (bot < top)
> - {
> - sym = BLOCK_SYM (block, bot);
> - if (SYMBOL_NAMESPACE (sym) == namespace
> - && (mangled_name
> - ? strcmp (DEPRECATED_SYMBOL_NAME (sym), mangled_name) == 0
> - : SYMBOL_MATCHES_NATURAL_NAME (sym, name)))
> {
> /* If SYM has aliases, then use any alias that is active
> at the current PC. If no alias is active at the current
> @@ -1795,18 +1709,18 @@ lookup_block_symbol (register const stru
> ?!? Is checking the current pc correct? Is this routine
> ever called to look up a symbol from another context?
>
> - FIXME: No, it's not correct. If someone sets a
> - conditional breakpoint at an address, then the
> - breakpoint's `struct expression' should refer to the
> - `struct symbol' appropriate for the breakpoint's
> - address, which may not be the PC.
> -
> - Even if it were never called from another context,
> - it's totally bizarre for lookup_symbol's behavior to
> - depend on the value of the inferior's current PC. We
> - should pass in the appropriate PC as well as the
> - block. The interface to lookup_symbol should change
> - to require the caller to provide a PC. */
> + FIXME: No, it's not correct. If someone sets a
> + conditional breakpoint at an address, then the
> + breakpoint's `struct expression' should refer to the
> + `struct symbol' appropriate for the breakpoint's
> + address, which may not be the PC.
> +
> + Even if it were never called from another context,
> + it's totally bizarre for lookup_symbol's behavior to
> + depend on the value of the inferior's current PC. We
> + should pass in the appropriate PC as well as the
> + block. The interface to lookup_symbol should change
> + to require the caller to provide a PC. */
>
> if (SYMBOL_ALIASES (sym))
> sym = find_active_alias (sym, read_pc ());
> @@ -1823,10 +1737,9 @@ lookup_block_symbol (register const stru
> break;
> }
> }
> - bot++;
> }
> + return (sym_found); /* Will be NULL if not found. */
> }
> - return (sym_found); /* Will be NULL if not found. */
> }
>
> /* Given a main symbol SYM and ADDR, search through the alias
> @@ -1929,16 +1842,16 @@ find_pc_sect_symtab (CORE_ADDR pc, asect
> }
> if (section != 0)
> {
> - int i;
> + struct dict_iterator iter;
> struct symbol *sym = NULL;
>
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> fixup_symbol_section (sym, objfile);
> if (section == SYMBOL_BFD_SECTION (sym))
> break;
> }
> - if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
> + if (sym == NULL)
> continue; /* no symbol in this symtab matches section */
> }
> distance = BLOCK_END (b) - BLOCK_START (b);
> @@ -2875,7 +2788,7 @@ search_symbols (char *regexp, namespace_
> struct blockvector *prev_bv = 0;
> register struct block *b;
> register int i = 0;
> - register int j;
> + struct dict_iterator iter;
> register struct symbol *sym;
> struct partial_symbol **psym;
> struct objfile *objfile;
> @@ -3064,7 +2977,7 @@ search_symbols (char *regexp, namespace_
> struct symbol_search *prevtail = tail;
> int nfound = 0;
> b = BLOCKVECTOR_BLOCK (bv, i);
> - ALL_BLOCK_SYMBOLS (b, j, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> QUIT;
> if (file_matches (s->filename, files, nfiles)
> @@ -3425,7 +3338,8 @@ make_symbol_completion_list (char *text,
> register struct minimal_symbol *msymbol;
> register struct objfile *objfile;
> register struct block *b, *surrounding_static_block = 0;
> - register int i, j;
> + struct dict_iterator iter;
> + register int j;

no need for register.

> struct partial_symbol **psym;
> /* The symbol we are completing on. Points in same buffer as text. */
> char *sym_text;
> @@ -3546,7 +3460,7 @@ make_symbol_completion_list (char *text,
> /* Also catch fields of types defined in this places which match our
> text string. Only complete on types visible from current context. */
>
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
> if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
> @@ -3576,7 +3490,7 @@ make_symbol_completion_list (char *text,
> {
> QUIT;
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
> }
> @@ -3589,7 +3503,7 @@ make_symbol_completion_list (char *text,
> /* Don't do this block twice. */
> if (b == surrounding_static_block)
> continue;
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
> }
> @@ -3607,7 +3521,7 @@ make_file_symbol_completion_list (char *
> register struct symbol *sym;
> register struct symtab *s;
> register struct block *b;
> - register int i;
> + struct dict_iterator iter;
> /* The symbol we are completing on. Points in same buffer as text. */
> char *sym_text;
> /* Length of sym_text. */
> @@ -3694,13 +3608,13 @@ make_file_symbol_completion_list (char *
> symbols which match. */
>
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
> }
>
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
> }
> @@ -4051,7 +3965,7 @@ make_symbol_overload_list (struct symbol
> register struct partial_symtab *ps;
> register struct objfile *objfile;
> register struct block *b, *surrounding_static_block = 0;
> - register int i;
> + struct dict_iterator iter;
> /* The name we are completing on. */
> char *oload_name = NULL;
> /* Length of name. */
> @@ -4108,7 +4022,7 @@ make_symbol_overload_list (struct symbol
> /* Also catch fields of types defined in this places which match our
> text string. Only complete on types visible from current context. */
>
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> overload_list_add_symbol (sym, oload_name);
> }
> @@ -4121,7 +4035,7 @@ make_symbol_overload_list (struct symbol
> {
> QUIT;
> b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> overload_list_add_symbol (sym, oload_name);
> }
> @@ -4134,7 +4048,7 @@ make_symbol_overload_list (struct symbol
> /* Don't do this block twice. */
> if (b == surrounding_static_block)
> continue;
> - ALL_BLOCK_SYMBOLS (b, i, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> overload_list_add_symbol (sym, oload_name);
> }
> Index: symtab.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/symtab.h,v
> retrieving revision 1.68
> diff -u -p -r1.68 symtab.h
> --- symtab.h 14 Apr 2003 19:55:27 -0000 1.68
> +++ symtab.h 30 Apr 2003 22:46:20 -0000
> @@ -819,10 +819,10 @@ struct symtab
> }
> free_code;
>
> - /* Pointer to one block of storage to be freed, if nonzero. */
> - /* This is IN ADDITION to the action indicated by free_code. */
> + /* A function to call to free space, if necessary. This is IN
> + ADDITION to the action indicated by free_code. */
>
> - char *free_ptr;
> + void (*free_func)(struct symtab *symtab);
>
> /* Total number of lines found in source file. */
>
> Index: tracepoint.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/tracepoint.c,v
> retrieving revision 1.49
> diff -u -p -r1.49 tracepoint.c
> --- tracepoint.c 25 Feb 2003 21:36:20 -0000 1.49
> +++ tracepoint.c 30 Apr 2003 22:46:24 -0000
> @@ -38,6 +38,7 @@
> #include "completer.h"
> #include "gdb-events.h"
> #include "block.h"
> +#include "dictionary.h"
>
> #include "ax.h"
> #include "ax-gdb.h"
> @@ -1289,13 +1290,14 @@ add_local_symbols (struct collection_lis
> {
> struct symbol *sym;
> struct block *block;
> - int i, count = 0;
> + struct dict_iterator iter;
> + int count = 0;
>
> block = block_for_pc (pc);
> while (block != 0)
> {
> QUIT; /* allow user to bail out with ^C */
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -2333,7 +2335,8 @@ scope_info (char *args, int from_tty)
> struct minimal_symbol *msym;
> struct block *block;
> char **canonical, *symname, *save_args = args;
> - int i, j, count = 0;
> + struct dict_iterator iter;
> + int j, count = 0;
>
> if (args == 0 || *args == 0)
> error ("requires an argument (function, line or *addr) to define a scope");
> @@ -2349,7 +2352,7 @@ scope_info (char *args, int from_tty)
> while (block != 0)
> {
> QUIT; /* allow user to bail out with ^C */
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> QUIT; /* allow user to bail out with ^C */
> if (count == 0)
> Index: valops.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/valops.c,v
> retrieving revision 1.105
> diff -u -p -r1.105 valops.c
> --- valops.c 21 Apr 2003 16:48:40 -0000 1.105
> +++ valops.c 30 Apr 2003 22:46:26 -0000
> @@ -35,6 +35,7 @@
> #include "cp-abi.h"
> #include "block.h"
> #include "infcall.h"
> +#include "dictionary.h"
>
> #include <errno.h>
> #include "gdb_string.h"
> @@ -2479,7 +2480,6 @@ value_of_local (const char *name, int co
> {
> struct symbol *func, *sym;
> struct block *b;
> - int i;
> struct value * ret;
>
> if (deprecated_selected_frame == 0)
> @@ -2500,8 +2500,7 @@ value_of_local (const char *name, int co
> }
>
> b = SYMBOL_BLOCK_VALUE (func);
> - i = BLOCK_NSYMS (b);
> - if (i <= 0)
> + if (dict_empty (BLOCK_DICT (b)))
> {
> if (complain)
> error ("no args, no `%s'", name);
> Index: gdbtk/generic/gdbtk-cmds.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbtk/generic/gdbtk-cmds.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 gdbtk-cmds.c
> --- gdbtk/generic/gdbtk-cmds.c 6 Mar 2003 21:58:41 -0000 1.72
> +++ gdbtk/generic/gdbtk-cmds.c 30 Apr 2003 22:46:31 -0000
> @@ -35,6 +35,7 @@
> #include "top.h"
> #include "annotate.h"
> #include "block.h"
> +#include "dictionary.h"
>
> /* tcl header files includes varargs.h unless HAS_STDARG is defined,
> but gdb uses stdarg.h, so make sure HAS_STDARG is defined. */
> @@ -1402,7 +1403,8 @@ gdb_listfuncs (clientData, interp, objc,
> struct blockvector *bv;
> struct block *b;
> struct symbol *sym;
> - int i, j;
> + int i;
> + struct dict_iterator iter;
> Tcl_Obj *funcVals[2];
>
> if (objc != 2)
> @@ -1433,7 +1435,7 @@ gdb_listfuncs (clientData, interp, objc,
> for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
> {
> b = BLOCKVECTOR_BLOCK (bv, i);
> - ALL_BLOCK_SYMBOLS (b, j, sym)
> + ALL_BLOCK_SYMBOLS (b, iter, sym)
> {
> if (SYMBOL_CLASS (sym) == LOC_BLOCK)
> {
> Index: gdbtk/generic/gdbtk-stack.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbtk/generic/gdbtk-stack.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 gdbtk-stack.c
> --- gdbtk/generic/gdbtk-stack.c 11 Apr 2003 17:40:23 -0000 1.18
> +++ gdbtk/generic/gdbtk-stack.c 30 Apr 2003 22:46:32 -0000
> @@ -23,6 +23,7 @@
> #include "breakpoint.h"
> #include "linespec.h"
> #include "block.h"
> +#include "dictionary.h"
>
> #include <tcl.h>
> #include "gdbtk.h"
> @@ -85,7 +86,7 @@ gdb_block_vars (ClientData clientData, T
> int objc, Tcl_Obj *CONST objv[])
> {
> struct block *block;
> - int i;
> + struct dict_iterator iter;
> struct symbol *sym;
> CORE_ADDR start, end;
>
> @@ -108,7 +109,7 @@ gdb_block_vars (ClientData clientData, T
> {
> if (BLOCK_START (block) == start && BLOCK_END (block) == end)
> {
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -160,7 +161,8 @@ gdb_get_blocks (ClientData clientData, T
> int objc, Tcl_Obj *CONST objv[])
> {
> struct block *block;
> - int i, junk;
> + struct dict_iterator iter;
> + int junk;
> struct symbol *sym;
> CORE_ADDR pc;
>
> @@ -173,7 +175,7 @@ gdb_get_blocks (ClientData clientData, T
> while (block != 0)
> {
> junk = 0;
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> @@ -280,6 +282,7 @@ gdb_get_vars_command (ClientData clientD
> struct symbol *sym;
> struct block *block;
> char **canonical, *args;
> + struct dict_iterator iter;
> int i, arguments;
>
> if (objc > 2)
> @@ -322,7 +325,7 @@ gdb_get_vars_command (ClientData clientD
>
> while (block != 0)
> {
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> switch (SYMBOL_CLASS (sym))
> {
> Index: mi/mi-cmd-stack.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/mi/mi-cmd-stack.c,v
> retrieving revision 1.16
> diff -u -p -r1.16 mi-cmd-stack.c
> --- mi/mi-cmd-stack.c 25 Feb 2003 21:36:23 -0000 1.16
> +++ mi/mi-cmd-stack.c 30 Apr 2003 22:46:35 -0000
> @@ -27,6 +27,7 @@
> #include "ui-out.h"
> #include "symtab.h"
> #include "block.h"
> +#include "dictionary.h"
>
> /* FIXME: these should go in some .h file but stack.c doesn't have a
> corresponding .h file. These wrappers will be obsolete anyway, once
> @@ -217,7 +218,8 @@ list_args_or_locals (int locals, int val
> {
> struct block *block;
> struct symbol *sym;
> - int i, nsyms;
> + struct dict_iterator iter;
> + int nsyms;
> struct cleanup *cleanup_list;
> static struct ui_stream *stb = NULL;
>
> @@ -229,7 +231,7 @@ list_args_or_locals (int locals, int val
>
> while (block != 0)
> {
> - ALL_BLOCK_SYMBOLS (block, i, sym)
> + ALL_BLOCK_SYMBOLS (block, iter, sym)
> {
> int print_me = 0;
>