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]

[rfa] struct dictionary


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?

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.

--- /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,
+  };
+
+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)
 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))
 		{
-		  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);
 
-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))
 		    {
-		      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;
   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;
+  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.  */
+
 	  /* 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;
   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]