This is the mail archive of the gdb-patches@sourceware.org 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]

[2/3] RFC: merge symbol "ops" and "aclass" fields


I never fully understood the plan to merge the "ops" and "aclass" fields
of struct symbol until I stumbled across PR 8421, which explains the
idea in a bit more detail than the FIXME comment in symtab.h.

This patch implements the idea outlined there.  We drop the "ops" field
entirely and replace "aclass" with "aclass_index" (the renaming makes it
obvious that there is a change).

The aclass_index is just an index into a table of "symbol_impl"
structures, which record the real address class and also the various ops
vectors.

For ordinary address_class constants, the index and the aclass are the
same.  This is ensured by some initialization code in symtab.c.

"Synthetic" indices are registered at initialization time by the various
symbol readers.

To find the address_class or an ops vector for a symbol, we simply look
in the global table using the symbol's aclass_index.

This saves a pointer per symbol.

Built and regtested on x86-64 Fedora 16.

Tom

	PR symtab/8421:
	* coffread.c (coff_register_index): New global.
	(process_coff_symbol, coff_read_enum_type): Set
	SYMBOL_ACLASS_INDEX.
	(_initialize_coffread): Initialize new global.
	* dwarf2loc.c (dwarf_expr_frame_base_1): Use SYMBOL_READER_DATUM.
	* dwarf2read.c (dwarf2_locexpr_index, dwarf2_loclist_index)
	(dwarf2_locexpr_block_index, dwarf2_loclist_block_index): New
	globals.
	(read_func_scope): Update.
	(fixup_go_packaging, mark_common_block_symbol_computed)
	(var_decode_location, new_symbol_full, dwarf2_const_value):
	Set SYMBOL_ACLASS_INDEX.
	(dwarf2_symbol_mark_computed): Likewise.  Add 'is_block' argument.
	(_initialize_dwarf2_read): Initialize new globals.
	* jit.c (finalize_symtab): Set SYMBOL_ACLASS_INDEX.
	* jv-lang.c (add_class_symbol): Set SYMBOL_ACLASS_INDEX.
	* mdebugread.c (mdebug_register_index, mdebug_regparm_index): New
	globals.
	(parse_symbol, psymtab_to_symtab_1): Set SYMBOL_ACLASS_INDEX.
	(_initialize_mdebugread): Initialize new globals.
	* psympriv.h (struct partial_symbol) <aclass>: Update comment.
	* stabsread.c (patch_block_stabs): Set SYMBOL_ACLASS_INDEX.
	(stab_register_index, stab_regparm_index): New globals.
	(define_symbol, read_enum_type, common_block_end): Set
	SYMBOL_ACLASS_INDEX.
	(_initialize_stabsread): Initialize new globals.
	* symtab.c (next_aclass_value, symbol_impl, symbol_impls): New
	globals.
	(MAX_SYMBOL_IMPLS): New define.
	(register_symbol_computed_impl, register_symbol_datum_impl)
	(register_symbol_register_impl)
	(initialize_ordinary_address_classes): New functions.
	(_initialize_symtab): Call initialize_ordinary_address_classes.
	* symtab.h (enum address_class) <LOC_FINAL_VALUE>: New constant.
	(struct symbol_impl): New.
	(SYMBOL_ACLASS_BITS): New define.
	(struct symbol) <aclass, ops>: Remove fields.
	<aclass_index>: New field.
	(symbol_impls): Declare.
	(SYMBOL_CLASS, SYMBOL_COMPUTED_OPS, SYMBOL_REGISTER_OPS): Redefine.
	(SYMBOL_ACLASS_INDEX, SYMBOL_READER_DATUM): New defines.
	(register_symbol_computed_impl, register_symbol_datum_impl)
	(register_symbol_register_impl): Declare.
	* xcoffread.c (process_xcoff_symbol): Set SYMBOL_ACLASS_INDEX.
---
 gdb/coffread.c   |   29 +++++++++-------
 gdb/dwarf2loc.c  |    2 +-
 gdb/dwarf2read.c |   75 ++++++++++++++++++++++++++---------------
 gdb/jit.c        |    2 +-
 gdb/jv-lang.c    |    2 +-
 gdb/mdebugread.c |   41 +++++++++++++----------
 gdb/psympriv.h   |    4 ++-
 gdb/stabsread.c  |   82 ++++++++++++++++++++++++---------------------
 gdb/symtab.c     |   97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/symtab.h     |   71 ++++++++++++++++++++++++++-------------
 gdb/xcoffread.c  |    2 +-
 11 files changed, 284 insertions(+), 123 deletions(-)

diff --git a/gdb/coffread.c b/gdb/coffread.c
index 9e62207..7720211 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -1531,6 +1531,10 @@ static const struct symbol_register_ops coff_register_funcs = {
   coff_reg_to_regnum
 };
 
+/* The "aclass" index for computed COFF symbols.  */
+
+static int coff_register_index;
+
 static struct symbol *
 process_coff_symbol (struct coff_symbol *cs,
 		     union internal_auxent *aux,
@@ -1560,7 +1564,7 @@ process_coff_symbol (struct coff_symbol *cs,
 	lookup_function_type (decode_function_type (cs, cs->c_type,
 						    aux, objfile));
 
-      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
       if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
 	  || cs->c_sclass == C_THUMBSTATFUNC)
 	add_symbol_to_list (sym, &file_symbols);
@@ -1577,14 +1581,14 @@ process_coff_symbol (struct coff_symbol *cs,
 	  break;
 
 	case C_AUTO:
-	  SYMBOL_CLASS (sym) = LOC_LOCAL;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_LOCAL;
 	  add_symbol_to_list (sym, &local_symbols);
 	  break;
 
 	case C_THUMBEXT:
 	case C_THUMBEXTFUNC:
 	case C_EXT:
-	  SYMBOL_CLASS (sym) = LOC_STATIC;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
 	  SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
 	  SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
 						  SECT_OFF_TEXT (objfile));
@@ -1594,7 +1598,7 @@ process_coff_symbol (struct coff_symbol *cs,
 	case C_THUMBSTAT:
 	case C_THUMBSTATFUNC:
 	case C_STAT:
-	  SYMBOL_CLASS (sym) = LOC_STATIC;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
 	  SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
 	  SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
 						  SECT_OFF_TEXT (objfile));
@@ -1614,8 +1618,7 @@ process_coff_symbol (struct coff_symbol *cs,
 	case C_GLBLREG:
 #endif
 	case C_REG:
-	  SYMBOL_CLASS (sym) = LOC_REGISTER;
-	  SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+	  SYMBOL_ACLASS_INDEX (sym) = coff_register_index;
 	  SYMBOL_VALUE (sym) = cs->c_value;
 	  add_symbol_to_list (sym, &local_symbols);
 	  break;
@@ -1625,21 +1628,20 @@ process_coff_symbol (struct coff_symbol *cs,
 	  break;
 
 	case C_ARG:
-	  SYMBOL_CLASS (sym) = LOC_ARG;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_ARG;
 	  SYMBOL_IS_ARGUMENT (sym) = 1;
 	  add_symbol_to_list (sym, &local_symbols);
 	  break;
 
 	case C_REGPARM:
-	  SYMBOL_CLASS (sym) = LOC_REGISTER;
-	  SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs;
+	  SYMBOL_ACLASS_INDEX (sym) = coff_register_index;
 	  SYMBOL_IS_ARGUMENT (sym) = 1;
 	  SYMBOL_VALUE (sym) = cs->c_value;
 	  add_symbol_to_list (sym, &local_symbols);
 	  break;
 
 	case C_TPDEF:
-	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 
 	  /* If type has no name, give it one.  */
@@ -1695,7 +1697,7 @@ process_coff_symbol (struct coff_symbol *cs,
 	case C_STRTAG:
 	case C_UNTAG:
 	case C_ENTAG:
-	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
 
 	  /* Some compilers try to be helpful by inventing "fake"
@@ -2106,7 +2108,7 @@ coff_read_enum_type (int index, int length, int lastsym,
 	  SYMBOL_SET_LINKAGE_NAME (sym,
 				   obsavestring (name, strlen (name),
 						 &objfile->objfile_obstack));
-	  SYMBOL_CLASS (sym) = LOC_CONST;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  SYMBOL_VALUE (sym) = ms->c_value;
 	  add_symbol_to_list (sym, symlist);
@@ -2209,4 +2211,7 @@ _initialize_coffread (void)
 
   coff_objfile_data_key = register_objfile_data_with_cleanup (NULL,
 							      coff_free_info);
+
+  coff_register_index
+    = register_symbol_register_impl (LOC_REGISTER, &coff_register_funcs);
 }
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 33300ee..76677f7 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -358,7 +358,7 @@ dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
 {
   if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
     *length = 0;
-  else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
+  else if (SYMBOL_READER_DATUM (framefunc) == &dwarf2_loclist_funcs)
     {
       struct dwarf2_loclist_baton *symbaton;
 
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 519eee8..a2819ca 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -97,6 +97,13 @@ static int processing_has_namespace_info;
 
 static const struct objfile_data *dwarf2_objfile_data_key;
 
+/* The "aclass" indices for various kinds of computed DWARF symbols.  */
+
+static int dwarf2_locexpr_index;
+static int dwarf2_loclist_index;
+static int dwarf2_locexpr_block_index;
+static int dwarf2_loclist_block_index;
+
 struct dwarf2_section_info
 {
   asection *asection;
@@ -1615,7 +1622,8 @@ static void fill_in_loclist_baton (struct dwarf2_cu *cu,
 
 static void dwarf2_symbol_mark_computed (struct attribute *attr,
 					 struct symbol *sym,
-					 struct dwarf2_cu *cu);
+					 struct dwarf2_cu *cu,
+					 int is_block);
 
 static gdb_byte *skip_one_die (const struct die_reader_specs *reader,
 			       gdb_byte *info_ptr,
@@ -6852,7 +6860,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
       /* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
 	 e.g., "main" finds the "main" module and not C's main().  */
       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
       SYMBOL_TYPE (sym) = type;
 
       add_symbol_to_list (sym, &global_symbols);
@@ -9529,7 +9537,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
        has nothing to do with the location of the function, ouch!  The
        relationship should be: a function's symbol has-a frame base; a
        frame-base has-a location expression.  */
-    dwarf2_symbol_mark_computed (attr, new->name, cu);
+    dwarf2_symbol_mark_computed (attr, new->name, cu, 1);
 
   cu->list_in_scope = &local_symbols;
 
@@ -11953,9 +11961,8 @@ mark_common_block_symbol_computed (struct symbol *sym,
   *ptr++ = DW_OP_plus;
   gdb_assert (ptr - baton->data == baton->size);
 
-  SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
   SYMBOL_LOCATION_BATON (sym) = baton;
-  SYMBOL_CLASS (sym) = LOC_COMPUTED;
+  SYMBOL_ACLASS_INDEX (sym) = dwarf2_locexpr_index;
 }
 
 /* Create appropriate locally-scoped variables for all the
@@ -15710,7 +15717,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
      variable has been optimized away.  */
   if (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0)
     {
-      SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
       return;
     }
 
@@ -15734,7 +15741,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
       else
 	SYMBOL_VALUE_ADDRESS (sym) =
 	  read_addr_index_from_leb128 (cu, DW_BLOCK (attr)->data + 1, &dummy);
-      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
       fixup_symbol_section (sym, objfile);
       SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
 					      SYMBOL_SECTION (sym));
@@ -15748,8 +15755,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
      not be worthwhile.  I'm assuming that it isn't unless performance
      or memory numbers show me otherwise.  */
 
-  dwarf2_symbol_mark_computed (attr, sym, cu);
-  SYMBOL_CLASS (sym) = LOC_COMPUTED;
+  dwarf2_symbol_mark_computed (attr, sym, cu, 0);
 
   if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs)
     cu->has_loclist = 1;
@@ -15807,7 +15813,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-      SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
       if (type != NULL)
 	SYMBOL_TYPE (sym) = type;
       else
@@ -15850,13 +15856,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	    }
 	  SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr;
 	  SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
-	  SYMBOL_CLASS (sym) = LOC_LABEL;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_LABEL;
 	  add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
 	case DW_TAG_subprogram:
 	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
 	     finish_block.  */
-	  SYMBOL_CLASS (sym) = LOC_BLOCK;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
 	  attr2 = dwarf2_attr (die, DW_AT_external, cu);
 	  if ((attr2 && (DW_UNSND (attr2) != 0))
               || cu->language == language_ada)
@@ -15877,7 +15883,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_inlined_subroutine:
 	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
 	     finish_block.  */
-	  SYMBOL_CLASS (sym) = LOC_BLOCK;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
 	  SYMBOL_INLINED (sym) = 1;
 	  list_to_add = cu->list_in_scope;
 	  break;
@@ -15952,7 +15958,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 		      && die->parent->tag == DW_TAG_module
 		      && cu->producer
 		      && strncmp (cu->producer, "GNU Fortran ", 12) == 0)
-		    SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+		    SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
 
 		  /* A variable with DW_AT_external is never static,
 		     but it may be block-scoped.  */
@@ -15990,7 +15996,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 		  list_to_add = (cu->list_in_scope == &file_symbols
 				 ? &global_symbols : cu->list_in_scope);
 
-		  SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+		  SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
 		}
 	      else if (!die_is_declaration (die, cu))
 		{
@@ -16037,7 +16043,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
 
 	  {
@@ -16074,13 +16080,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  }
 	  break;
 	case DW_TAG_typedef:
-	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  list_to_add = cu->list_in_scope;
 	  break;
 	case DW_TAG_base_type:
         case DW_TAG_subrange_type:
-	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  list_to_add = cu->list_in_scope;
 	  break;
@@ -16101,11 +16107,11 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  }
 	  break;
 	case DW_TAG_namespace:
-	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
 	  list_to_add = &global_symbols;
 	  break;
 	case DW_TAG_common_block:
-	  SYMBOL_CLASS (sym) = LOC_STATIC;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
 	  SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
 	  add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
@@ -16312,19 +16318,18 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
 
   if (baton != NULL)
     {
-      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
-      SYMBOL_CLASS (sym) = LOC_COMPUTED;
+      SYMBOL_ACLASS_INDEX (sym) = dwarf2_locexpr_index;
     }
   else if (bytes != NULL)
      {
       SYMBOL_VALUE_BYTES (sym) = bytes;
-      SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST_BYTES;
     }
   else
     {
       SYMBOL_VALUE (sym) = value;
-      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
     }
 }
 
@@ -19035,7 +19040,7 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
 
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
-			     struct dwarf2_cu *cu)
+			     struct dwarf2_cu *cu, int is_block)
 {
   struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_section_info *section = cu_debug_loc_section (cu);
@@ -19058,7 +19063,9 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 		   _("Location list used without "
 		     "specifying the CU base address."));
 
-      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs;
+      SYMBOL_ACLASS_INDEX (sym) = (is_block
+				   ? dwarf2_loclist_block_index
+				   : dwarf2_loclist_index);
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
   else
@@ -19087,7 +19094,9 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 	  baton->size = 0;
 	}
 
-      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_ACLASS_INDEX (sym) = (is_block
+				   ? dwarf2_locexpr_block_index
+				   : dwarf2_locexpr_index);
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
 }
@@ -20689,4 +20698,16 @@ Save a gdb-index file.\n\
 Usage: save gdb-index DIRECTORY"),
 	       &save_cmdlist);
   set_cmd_completer (c, filename_completer);
+
+  dwarf2_locexpr_index = register_symbol_computed_impl (LOC_COMPUTED,
+							&dwarf2_locexpr_funcs);
+  dwarf2_loclist_index = register_symbol_computed_impl (LOC_COMPUTED,
+							&dwarf2_loclist_funcs);
+
+  /* In these two calls, the _funcs vectors aren't actually used; they
+     are just sentinels for other checks.  */
+  dwarf2_locexpr_block_index
+    = register_symbol_datum_impl (LOC_BLOCK, &dwarf2_locexpr_funcs);
+  dwarf2_loclist_block_index
+    = register_symbol_datum_impl (LOC_BLOCK, &dwarf2_loclist_funcs);
 }
diff --git a/gdb/jit.c b/gdb/jit.c
index a930f74..63dc788 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -674,7 +674,7 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile)
       /* The name.  */
       memset (block_name, 0, sizeof (struct symbol));
       SYMBOL_DOMAIN (block_name) = VAR_DOMAIN;
-      SYMBOL_CLASS (block_name) = LOC_BLOCK;
+      SYMBOL_ACLASS_INDEX (block_name) = LOC_BLOCK;
       SYMBOL_SYMTAB (block_name) = symtab;
       SYMBOL_TYPE (block_name) = lookup_function_type (block_type);
       SYMBOL_BLOCK_VALUE (block_name) = new_block;
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index f8e8718..b4ef310 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -190,7 +190,7 @@ add_class_symbol (struct type *type, CORE_ADDR addr)
   memset (sym, 0, sizeof (struct symbol));
   SYMBOL_SET_LANGUAGE (sym, language_java);
   SYMBOL_SET_LINKAGE_NAME (sym, TYPE_TAG_NAME (type));
-  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
   /*  SYMBOL_VALUE (sym) = valu; */
   SYMBOL_TYPE (sym) = type;
   SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index 2eb0536..26bfd59 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -541,6 +541,11 @@ static const struct symbol_register_ops mdebug_register_funcs = {
   mdebug_reg_to_regnum
 };
 
+/* The "aclass" indices for computed symbols.  */
+
+static int mdebug_register_index;
+static int mdebug_regparm_index;
+
 static int
 parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 	      struct section_offsets *section_offsets, struct objfile *objfile)
@@ -625,16 +630,13 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
       s = new_symbol (name);
       SYMBOL_VALUE (s) = svalue;
       if (sh->sc == scRegister)
-	{
-	  class = LOC_REGISTER;
-	  SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
-	}
+	class = mdebug_register_index;
       else
 	class = LOC_LOCAL;
 
     data:			/* Common code for symbols describing data.  */
       SYMBOL_DOMAIN (s) = VAR_DOMAIN;
-      SYMBOL_CLASS (s) = class;
+      SYMBOL_ACLASS_INDEX (s) = class;
       add_symbol (s, top_stack->cur_st, b);
 
       /* Type could be missing if file is compiled without debugging info.  */
@@ -663,21 +665,19 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 	{
 	case scRegister:
 	  /* Pass by value in register.  */
-	  SYMBOL_CLASS (s) = LOC_REGISTER;
-	  SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
+	  SYMBOL_ACLASS_INDEX (s) = mdebug_register_index;
 	  break;
 	case scVar:
 	  /* Pass by reference on stack.  */
-	  SYMBOL_CLASS (s) = LOC_REF_ARG;
+	  SYMBOL_ACLASS_INDEX (s) = LOC_REF_ARG;
 	  break;
 	case scVarRegister:
 	  /* Pass by reference in register.  */
-	  SYMBOL_CLASS (s) = LOC_REGPARM_ADDR;
-	  SYMBOL_REGISTER_OPS (s) = &mdebug_register_funcs;
+	  SYMBOL_ACLASS_INDEX (s) = mdebug_regparm_index;
 	  break;
 	default:
 	  /* Pass by value on stack.  */
-	  SYMBOL_CLASS (s) = LOC_ARG;
+	  SYMBOL_ACLASS_INDEX (s) = LOC_ARG;
 	  break;
 	}
       SYMBOL_VALUE (s) = svalue;
@@ -688,7 +688,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
     case stLabel:		/* label, goes into current block.  */
       s = new_symbol (name);
       SYMBOL_DOMAIN (s) = VAR_DOMAIN;	/* So that it can be used */
-      SYMBOL_CLASS (s) = LOC_LABEL;	/* but not misused.  */
+      SYMBOL_ACLASS_INDEX (s) = LOC_LABEL;	/* but not misused.  */
       SYMBOL_VALUE_ADDRESS (s) = (CORE_ADDR) sh->value;
       SYMBOL_TYPE (s) = objfile_type (objfile)->builtin_int;
       add_symbol (s, top_stack->cur_st, top_stack->cur_block);
@@ -730,7 +730,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
         }
       s = new_symbol (name);
       SYMBOL_DOMAIN (s) = VAR_DOMAIN;
-      SYMBOL_CLASS (s) = LOC_BLOCK;
+      SYMBOL_ACLASS_INDEX (s) = LOC_BLOCK;
       /* Type of the return value.  */
       if (SC_IS_UNDEF (sh->sc) || sh->sc == scNil)
 	t = objfile_type (objfile)->builtin_int;
@@ -1054,7 +1054,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 		SYMBOL_SET_LINKAGE_NAME
 		  (enum_sym, obsavestring (f->name, strlen (f->name),
 					   &mdebugread_objfile->objfile_obstack));
-		SYMBOL_CLASS (enum_sym) = LOC_CONST;
+		SYMBOL_ACLASS_INDEX (enum_sym) = LOC_CONST;
 		SYMBOL_TYPE (enum_sym) = t;
 		SYMBOL_DOMAIN (enum_sym) = VAR_DOMAIN;
 		SYMBOL_VALUE (enum_sym) = tsym.value;
@@ -1087,7 +1087,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 
 	s = new_symbol (name);
 	SYMBOL_DOMAIN (s) = STRUCT_DOMAIN;
-	SYMBOL_CLASS (s) = LOC_TYPEDEF;
+	SYMBOL_ACLASS_INDEX (s) = LOC_TYPEDEF;
 	SYMBOL_VALUE (s) = 0;
 	SYMBOL_TYPE (s) = t;
 	add_symbol (s, top_stack->cur_st, top_stack->cur_block);
@@ -1143,7 +1143,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 	  /* Make up special symbol to contain procedure specific info.  */
 	  s = new_symbol (MDEBUG_EFI_SYMBOL_NAME);
 	  SYMBOL_DOMAIN (s) = LABEL_DOMAIN;
-	  SYMBOL_CLASS (s) = LOC_CONST;
+	  SYMBOL_ACLASS_INDEX (s) = LOC_CONST;
 	  SYMBOL_TYPE (s) = objfile_type (mdebugread_objfile)->builtin_void;
 	  e = ((struct mdebug_extra_func_info *)
 	       obstack_alloc (&mdebugread_objfile->objfile_obstack,
@@ -1283,7 +1283,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 	break;
       s = new_symbol (name);
       SYMBOL_DOMAIN (s) = VAR_DOMAIN;
-      SYMBOL_CLASS (s) = LOC_TYPEDEF;
+      SYMBOL_ACLASS_INDEX (s) = LOC_TYPEDEF;
       SYMBOL_BLOCK_VALUE (s) = top_stack->cur_block;
       SYMBOL_TYPE (s) = t;
       add_symbol (s, top_stack->cur_st, top_stack->cur_block);
@@ -4116,7 +4116,7 @@ psymtab_to_symtab_1 (struct objfile *objfile,
 
 		  memset (e, 0, sizeof (struct mdebug_extra_func_info));
 		  SYMBOL_DOMAIN (s) = LABEL_DOMAIN;
-		  SYMBOL_CLASS (s) = LOC_CONST;
+		  SYMBOL_ACLASS_INDEX (s) = LOC_CONST;
 		  SYMBOL_TYPE (s) = objfile_type (objfile)->builtin_void;
 		  SYMBOL_VALUE_BYTES (s) = (gdb_byte *) e;
 		  e->pdr.framereg = -1;
@@ -4936,4 +4936,9 @@ void
 _initialize_mdebugread (void)
 {
   basic_type_data = register_objfile_data ();
+
+  mdebug_register_index
+    = register_symbol_register_impl (LOC_REGISTER, &mdebug_register_funcs);
+  mdebug_regparm_index
+    = register_symbol_register_impl (LOC_REGPARM_ADDR, &mdebug_register_funcs);
 }
diff --git a/gdb/psympriv.h b/gdb/psympriv.h
index 815cc08..54eb804 100644
--- a/gdb/psympriv.h
+++ b/gdb/psympriv.h
@@ -45,7 +45,9 @@ struct partial_symbol
 
   ENUM_BITFIELD(domain_enum_tag) domain : 6;
 
-  /* Address class (for info_symbols).  */
+  /* Address class (for info_symbols).  Note that we don't allow
+     synthetic "aclass" values here at present, simply because there's
+     no need.  */
 
   ENUM_BITFIELD(address_class) aclass : 6;
 
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index f89dbae..5cc081b 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -385,7 +385,7 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs,
 
 	      memset (sym, 0, sizeof (struct symbol));
 	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
-	      SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
 	      SYMBOL_SET_LINKAGE_NAME
 		(sym, obsavestring (name, pp - name,
 				    &objfile->objfile_obstack));
@@ -604,6 +604,11 @@ static const struct symbol_register_ops stab_register_funcs = {
   stab_reg_to_regnum
 };
 
+/* The "aclass" indices for computed symbols.  */
+
+static int stab_register_index;
+static int stab_regparm_index;
+
 struct symbol *
 define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	       struct objfile *objfile)
@@ -761,7 +766,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
          (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
       if (*p != '=')
 	{
-	  SYMBOL_CLASS (sym) = LOC_CONST;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 	  SYMBOL_TYPE (sym) = error_type (&p, objfile);
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  add_symbol_to_list (sym, &file_symbols);
@@ -788,7 +793,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
 	    SYMBOL_TYPE (sym) = dbl_type;
 	    SYMBOL_VALUE_BYTES (sym) = dbl_valu;
-	    SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+	    SYMBOL_ACLASS_INDEX (sym) = LOC_CONST_BYTES;
 	  }
 	  break;
 	case 'i':
@@ -802,7 +807,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
 	    SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_long;
 	    SYMBOL_VALUE (sym) = atoi (p);
-	    SYMBOL_CLASS (sym) = LOC_CONST;
+	    SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 	  }
 	  break;
 
@@ -810,7 +815,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	  {
 	    SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_char;
 	    SYMBOL_VALUE (sym) = atoi (p);
-	    SYMBOL_CLASS (sym) = LOC_CONST;
+	    SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 	  }
 	  break;
 
@@ -824,7 +829,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
 	    if (quote != '\'' && quote != '"')
 	      {
-		SYMBOL_CLASS (sym) = LOC_CONST;
+		SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 		SYMBOL_TYPE (sym) = error_type (&p, objfile);
 		SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 		add_symbol_to_list (sym, &file_symbols);
@@ -849,7 +854,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	      }
 	    if (*p != quote)
 	      {
-		SYMBOL_CLASS (sym) = LOC_CONST;
+		SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 		SYMBOL_TYPE (sym) = error_type (&p, objfile);
 		SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 		add_symbol_to_list (sym, &file_symbols);
@@ -870,7 +875,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	    p++;
 
 	    SYMBOL_VALUE_BYTES (sym) = string_value;
-	    SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+	    SYMBOL_ACLASS_INDEX (sym) = LOC_CONST_BYTES;
 	  }
 	  break;
 
@@ -880,7 +885,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	     e.g. "b:c=e6,0" for "const b = blob1"
 	     (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
 	  {
-	    SYMBOL_CLASS (sym) = LOC_CONST;
+	    SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 	    SYMBOL_TYPE (sym) = read_type (&p, objfile);
 
 	    if (*p != ',')
@@ -901,7 +906,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	  break;
 	default:
 	  {
-	    SYMBOL_CLASS (sym) = LOC_CONST;
+	    SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
 	    SYMBOL_TYPE (sym) = error_type (&p, objfile);
 	  }
 	}
@@ -912,7 +917,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'C':
       /* The name of a caught exception.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_LABEL;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_LABEL;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
       add_symbol_to_list (sym, &local_symbols);
@@ -921,7 +926,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'f':
       /* A static function definition.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &file_symbols);
       /* fall into process_function_types.  */
@@ -992,7 +997,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'F':
       /* A global function definition.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &global_symbols);
       goto process_function_types;
@@ -1003,7 +1008,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
          corresponding linker definition to find the value.
          These definitions appear at the end of the namelist.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       /* Don't add symbol references to global_sym_chain.
          Symbol references don't have valid names and wont't match up with
@@ -1024,7 +1029,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 's':
     case 'l':
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_LOCAL;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_LOCAL;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
@@ -1044,7 +1049,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       else
 	SYMBOL_TYPE (sym) = read_type (&p, objfile);
 
-      SYMBOL_CLASS (sym) = LOC_ARG;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_ARG;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       SYMBOL_IS_ARGUMENT (sym) = 1;
@@ -1092,8 +1097,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'R':
       /* Parameter which is in a register.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_REGISTER;
-      SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
+      SYMBOL_ACLASS_INDEX (sym) = stab_register_index;
       SYMBOL_IS_ARGUMENT (sym) = 1;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
@@ -1103,8 +1107,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'r':
       /* Register variable (either global or local).  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_REGISTER;
-      SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
+      SYMBOL_ACLASS_INDEX (sym) = stab_register_index;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       if (within_function)
@@ -1141,8 +1144,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 		  && strcmp (SYMBOL_LINKAGE_NAME (prev_sym),
 			     SYMBOL_LINKAGE_NAME (sym)) == 0)
 		{
-		  SYMBOL_CLASS (prev_sym) = LOC_REGISTER;
-		  SYMBOL_REGISTER_OPS (prev_sym) = &stab_register_funcs;
+		  SYMBOL_ACLASS_INDEX (prev_sym) = stab_register_index;
 		  /* Use the type from the LOC_REGISTER; that is the type
 		     that is actually in that register.  */
 		  SYMBOL_TYPE (prev_sym) = SYMBOL_TYPE (sym);
@@ -1160,7 +1162,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'S':
       /* Static symbol at top level of file.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
       if (gdbarch_static_transform_name_p (gdbarch)
 	  && gdbarch_static_transform_name (gdbarch,
@@ -1209,7 +1211,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       if (nameless)
 	return NULL;
 
-      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       /* C++ vagaries: we may have a type which is derived from
@@ -1294,7 +1296,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
             obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
 
           *struct_sym = *sym;
-          SYMBOL_CLASS (struct_sym) = LOC_TYPEDEF;
+          SYMBOL_ACLASS_INDEX (struct_sym) = LOC_TYPEDEF;
           SYMBOL_VALUE (struct_sym) = valu;
           SYMBOL_DOMAIN (struct_sym) = STRUCT_DOMAIN;
           if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
@@ -1322,7 +1324,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       if (nameless)
 	return NULL;
 
-      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
       if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
@@ -1339,7 +1341,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	    obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
 
 	  *typedef_sym = *sym;
-	  SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF;
+	  SYMBOL_ACLASS_INDEX (typedef_sym) = LOC_TYPEDEF;
 	  SYMBOL_VALUE (typedef_sym) = valu;
 	  SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
 	  if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
@@ -1354,7 +1356,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'V':
       /* Static symbol of local scope.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_STATIC;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
       if (gdbarch_static_transform_name_p (gdbarch)
 	  && gdbarch_static_transform_name (gdbarch,
@@ -1381,7 +1383,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'v':
       /* Reference parameter */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_REF_ARG;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_REF_ARG;
       SYMBOL_IS_ARGUMENT (sym) = 1;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
@@ -1391,8 +1393,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
     case 'a':
       /* Reference parameter which is in a register.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
-      SYMBOL_REGISTER_OPS (sym) = &stab_register_funcs;
+      SYMBOL_ACLASS_INDEX (sym) = stab_regparm_index;
       SYMBOL_IS_ARGUMENT (sym) = 1;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
@@ -1405,7 +1406,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
          that Pascal uses it too, but when I tried it Pascal used
          "x:3" (local symbol) instead.  */
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_LOCAL;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_LOCAL;
       SYMBOL_VALUE (sym) = valu;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &local_symbols);
@@ -1413,7 +1414,7 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 
     default:
       SYMBOL_TYPE (sym) = error_type (&p, objfile);
-      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
       SYMBOL_VALUE (sym) = 0;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &file_symbols);
@@ -1430,11 +1431,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       /* We have to convert LOC_REGISTER to LOC_REGPARM_ADDR (for
          variables passed in a register).  */
       if (SYMBOL_CLASS (sym) == LOC_REGISTER)
-	SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+	SYMBOL_ACLASS_INDEX (sym) = LOC_REGPARM_ADDR;
       /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th
 	 and subsequent arguments on SPARC, for example).  */
       else if (SYMBOL_CLASS (sym) == LOC_ARG)
-	SYMBOL_CLASS (sym) = LOC_REF_ARG;
+	SYMBOL_ACLASS_INDEX (sym) = LOC_REF_ARG;
     }
 
   return sym;
@@ -3685,7 +3686,7 @@ read_enum_type (char **pp, struct type *type,
       memset (sym, 0, sizeof (struct symbol));
       SYMBOL_SET_LINKAGE_NAME (sym, name);
       SYMBOL_SET_LANGUAGE (sym, current_subfile->language);
-      SYMBOL_CLASS (sym) = LOC_CONST;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       SYMBOL_VALUE (sym) = n;
       if (n < 0)
@@ -4359,7 +4360,7 @@ common_block_end (struct objfile *objfile)
   memset (sym, 0, sizeof (struct symbol));
   /* Note: common_block_name already saved on objfile_obstack.  */
   SYMBOL_SET_LINKAGE_NAME (sym, common_block_name);
-  SYMBOL_CLASS (sym) = LOC_BLOCK;
+  SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
 
   /* Now we copy all the symbols which have been defined since the BCOMM.  */
 
@@ -4729,7 +4730,7 @@ scan_file_globals (struct objfile *objfile)
 
 	  /* Complain about unresolved common block symbols.  */
 	  if (SYMBOL_CLASS (prev) == LOC_STATIC)
-	    SYMBOL_CLASS (prev) = LOC_UNRESOLVED;
+	    SYMBOL_ACLASS_INDEX (prev) = LOC_UNRESOLVED;
 	  else
 	    complaint (&symfile_complaints,
 		       _("%s: common block `%s' from "
@@ -4844,4 +4845,9 @@ _initialize_stabsread (void)
   noname_undefs_length = 0;
   noname_undefs = (struct nat *)
     xmalloc (noname_undefs_allocated * sizeof (struct nat));
+
+  stab_register_index = register_symbol_register_impl (LOC_REGISTER,
+						       &stab_register_funcs);
+  stab_regparm_index = register_symbol_register_impl (LOC_REGPARM_ADDR,
+						      &stab_register_funcs);
 }
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f4ed8b9..6256d9d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -5043,9 +5043,106 @@ producer_is_realview (const char *producer)
   return 0;
 }
 
+
+
+/* The next index to hand out in response to a registration request.  */
+
+static int next_aclass_value = LOC_FINAL_VALUE;
+
+/* The maximum number of "aclass" registrations we support.  This is
+   constant for convenience.  */
+#define MAX_SYMBOL_IMPLS (LOC_FINAL_VALUE + 10)
+
+/* The objects representing the various "aclass" values.  The elements
+   from 0 up to LOC_FINAL_VALUE-1 represent themselves, and subsequent
+   elements are those registered at gdb initialization time.  */
+
+static struct symbol_impl symbol_impl[MAX_SYMBOL_IMPLS];
+
+/* The globally visible pointer.  This is separate from 'symbol_impl'
+   so that it can be const.  */
+
+const struct symbol_impl *symbol_impls = &symbol_impl[0];
+
+/* Make sure we saved enough room in struct symbol.  */
+
+gdb_static_assert (MAX_SYMBOL_IMPLS <= (1 << SYMBOL_ACLASS_BITS));
+
+/* Register a computed symbol type.  ACLASS must be LOC_COMPUTED.  OPS
+   is the ops vector associated with this index.  This returns the new
+   index, which should be used as the aclass_index field for symbols
+   of this type.  */
+
+int
+register_symbol_computed_impl (enum address_class aclass,
+			       const struct symbol_computed_ops *ops)
+{
+  int result = next_aclass_value++;
+
+  gdb_assert (aclass == LOC_COMPUTED);
+  gdb_assert (result < MAX_SYMBOL_IMPLS);
+  symbol_impl[result].aclass = aclass;
+  symbol_impl[result].ops_computed = ops;
+
+  return result;
+}
+
+/* Register a "datum" symbol type.  ACLASS can be anything.  DATUM is
+   a bit of per-symbol-reader data to store with this index.  This
+   returns the new index, which should be used as the aclass_index
+   field for symbols of this type.  */
+
+int
+register_symbol_datum_impl (enum address_class aclass, const void *datum)
+{
+  int result = next_aclass_value++;
+
+  gdb_assert (aclass >= 0 && aclass < LOC_FINAL_VALUE);
+  gdb_assert (result < MAX_SYMBOL_IMPLS);
+  symbol_impl[result].aclass = aclass;
+  symbol_impl[result].reader_datum = datum;
+
+  return result;
+}
+
+/* Register a register symbol type.  ACLASS must be LOC_REGISTER or
+   LOC_REGPARM_ADDR.  OPS is the register ops vector associated with
+   this index.  This returns the new index, which should be used as
+   the aclass_index field for symbols of this type.  */
+
+int
+register_symbol_register_impl (enum address_class aclass,
+			       const struct symbol_register_ops *ops)
+{
+  int result = next_aclass_value++;
+
+  gdb_assert (aclass == LOC_REGISTER || aclass == LOC_REGPARM_ADDR);
+  gdb_assert (result < MAX_SYMBOL_IMPLS);
+  symbol_impl[result].aclass = aclass;
+  symbol_impl[result].ops_register = ops;
+
+  return result;
+}
+
+/* Initialize elements of 'symbol_impl' for the constants in enum
+   address_class.  */
+
+static void
+initialize_ordinary_address_classes (void)
+{
+  int i;
+
+  for (i = 0; i < LOC_FINAL_VALUE; ++i)
+    symbol_impl[i].aclass = i;
+}
+
+
+
 void
 _initialize_symtab (void)
 {
+  initialize_ordinary_address_classes ();
+
   add_info ("variables", variables_info, _("\
 All global and static variable names, or those matching REGEXP."));
   if (dbx_commands)
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 78af1a2..7ec6821 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -533,6 +533,9 @@ enum address_class
   /* The variable's address is computed by a set of location
      functions (see "struct symbol_computed_ops" below).  */
   LOC_COMPUTED,
+
+  /* Not used, just notes the boundary of the enum.  */
+  LOC_FINAL_VALUE
 };
 
 /* The methods needed to implement LOC_COMPUTED.  These methods can
@@ -584,6 +587,30 @@ struct symbol_register_ops
   int (*register_number) (struct symbol *symbol, struct gdbarch *gdbarch);
 };
 
+/* Objects of this type are used to find the address class and the
+   various computed ops vectors of a symbol.  */
+
+struct symbol_impl
+{
+  enum address_class aclass;
+
+  /* Used with LOC_COMPUTED.  */
+  const struct symbol_computed_ops *ops_computed;
+
+  /* Used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
+  const struct symbol_register_ops *ops_register;
+
+  /* Used to store a per-symbol-reader datum.  */
+  const void *reader_datum;
+};
+
+/* The number of bits we reserve in a symbol for the aclass index.
+   This is a #define so that we can have a assertion elsewhere to
+   verify that we have reserved enough space for synthetic address
+   classes.  */
+
+#define SYMBOL_ACLASS_BITS 6
+
 /* This structure is space critical.  See space comments at the top.  */
 
 struct symbol
@@ -606,15 +633,11 @@ struct symbol
 
   ENUM_BITFIELD(domain_enum_tag) domain : 6;
 
-  /* Address class */
-  /* NOTE: cagney/2003-11-02: The fields "aclass" and "ops" contain
-     overlapping information.  By creating a per-aclass ops vector, or
-     using the aclass as an index into an ops table, the aclass and
-     ops fields can be merged.  The latter, for instance, would shave
-     32-bits from each symbol (relative to a symbol lookup, any table
-     index overhead would be in the noise).  */
+  /* Address class.  This holds an index into the 'symbol_impls'
+     table.  The actual enum address_class value is stored there,
+     alongside any per-class ops vectors.  */
 
-  ENUM_BITFIELD(address_class) aclass : 6;
+  unsigned int aclass_index : SYMBOL_ACLASS_BITS;
 
   /* Whether this is an argument.  */
 
@@ -639,18 +662,6 @@ struct symbol
 
   unsigned short line;
 
-  /* Method's for symbol's of this class.  */
-  /* NOTE: cagney/2003-11-02: See comment above attached to "aclass".  */
-
-  union
-    {
-      /* Used with LOC_COMPUTED.  */
-      const struct symbol_computed_ops *ops_computed;
-
-      /* Used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
-      const struct symbol_register_ops *ops_register;
-    } ops;
-
   /* An arbitrary data pointer, allowing symbol readers to record
      additional information on a per-symbol basis.  Note that this data
      must be allocated using the same obstack as the symbol itself.  */
@@ -669,9 +680,11 @@ struct symbol
   struct symbol *hash_next;
 };
 
+extern const struct symbol_impl *symbol_impls;
 
 #define SYMBOL_DOMAIN(symbol)	(symbol)->domain
-#define SYMBOL_CLASS(symbol)		(symbol)->aclass
+#define SYMBOL_ACLASS_INDEX(symbol)	(symbol)->aclass_index
+#define SYMBOL_CLASS(symbol)	((symbol_impls[(symbol)->aclass_index]).aclass)
 #define SYMBOL_IS_ARGUMENT(symbol)	(symbol)->is_argument
 #define SYMBOL_INLINED(symbol)		(symbol)->is_inlined
 #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \
@@ -679,10 +692,22 @@ struct symbol
 #define SYMBOL_TYPE(symbol)		(symbol)->type
 #define SYMBOL_LINE(symbol)		(symbol)->line
 #define SYMBOL_SYMTAB(symbol)		(symbol)->symtab
-#define SYMBOL_COMPUTED_OPS(symbol)     (symbol)->ops.ops_computed
-#define SYMBOL_REGISTER_OPS(symbol)     (symbol)->ops.ops_register
+#define SYMBOL_COMPUTED_OPS(symbol) \
+  ((symbol_impls[(symbol)->aclass_index]).ops_computed)
+#define SYMBOL_REGISTER_OPS(symbol) \
+  ((symbol_impls[(symbol)->aclass_index]).ops_register)
+#define SYMBOL_READER_DATUM(symbol) \
+  ((symbol_impls[(symbol)->aclass_index]).reader_datum)
 #define SYMBOL_LOCATION_BATON(symbol)   (symbol)->aux_value
 
+extern int register_symbol_computed_impl (enum address_class,
+					  const struct symbol_computed_ops *);
+
+extern int register_symbol_datum_impl (enum address_class, const void *);
+
+extern int register_symbol_register_impl (enum address_class,
+					  const struct symbol_register_ops *);
+
 /* An instance of this type is used to represent a C++ template
    function.  It includes a "struct symbol" as a kind of base class;
    users downcast to "struct template_symbol *" when needed.  A symbol
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index 41aaf02..ef4d178 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -1562,7 +1562,7 @@ process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile)
       SYMBOL_SET_LINKAGE_NAME (sym, SYMNAME_ALLOC (name, symname_alloced));
       SYMBOL_TYPE (sym) = objfile_type (objfile)->nodebug_text_symbol;
 
-      SYMBOL_CLASS (sym) = LOC_BLOCK;
+      SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
       SYMBOL_DUP (sym, sym2);
 
       if (cs->c_sclass == C_EXT)
-- 
1.7.7.6


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