This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfa] struct dictionary


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;
 >  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]