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]

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


>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

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

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

Here is a version of this patch which incorporates Jan's various
changes.

I plan to check it in soon, barring additional comments.

Bootstrapped and regtested on x86-64 Fedora 16.

Tom

2013-03-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	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 (locexpr_find_frame_base_location)
	(dwarf2_block_frame_base_locexpr_funcs)
	(loclist_find_frame_base_location)
	(dwarf2_block_frame_base_loclist_funcs): New.
	(dwarf_expr_frame_base_1): Call SYMBOL_BLOCK_OPS, remove internal_error.
	(dwarf2_locexpr_funcs, dwarf2_loclist_funcs): Add location_has_loclist.
	* dwarf2loc.h (dwarf2_block_frame_base_locexpr_funcs)
	(dwarf2_block_frame_base_loclist_funcs): New.
	* 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_block_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_IMPL, SYMBOL_ACLASS_INDEX): New defines.
	(register_symbol_computed_impl, register_symbol_block_impl)
	(register_symbol_register_impl): Declare.
	(struct symbol_computed_ops): Add location_has_loclist.
	(struct symbol_block_ops): New.
	(SYMBOL_BLOCK_OPS): New.
	* xcoffread.c (process_xcoff_symbol): Set SYMBOL_ACLASS_INDEX.
---
 gdb/coffread.c   |   29 +++++++++------
 gdb/dwarf2loc.c  |   65 +++++++++++++++++++++++++---------
 gdb/dwarf2loc.h  |    3 ++
 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     |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/symtab.h     |   87 ++++++++++++++++++++++++++++++++++------------
 gdb/xcoffread.c  |    2 +-
 12 files changed, 353 insertions(+), 141 deletions(-)

diff --git a/gdb/coffread.c b/gdb/coffread.c
index 3cc14ce..c390880 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -1529,6 +1529,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,
@@ -1558,7 +1562,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);
@@ -1575,14 +1579,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));
@@ -1592,7 +1596,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));
@@ -1612,8 +1616,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;
@@ -1623,21 +1626,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.  */
@@ -1693,7 +1695,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"
@@ -2104,7 +2106,7 @@ coff_read_enum_type (int index, int length, int lastsym,
 	  SYMBOL_SET_LINKAGE_NAME (sym,
 				   obstack_copy0 (&objfile->objfile_obstack,
 						  name, strlen (name)));
-	  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);
@@ -2207,4 +2209,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 625d859..700d194 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -357,32 +357,59 @@ dwarf_expr_frame_base (void *baton, const gdb_byte **start, size_t * length)
 			   start, length);
 }
 
+/* Implement find_frame_base_location method for LOC_BLOCK functions using
+   DWARF expression for its DW_AT_frame_base.  */
+
+static void
+locexpr_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
+				  const gdb_byte **start, size_t *length)
+{
+  struct dwarf2_locexpr_baton *symbaton = SYMBOL_LOCATION_BATON (framefunc);
+
+  *length = symbaton->size;
+  *start = symbaton->data;
+}
+
+/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
+   function uses DWARF expression for its DW_AT_frame_base.  */
+
+const struct symbol_block_ops dwarf2_block_frame_base_locexpr_funcs =
+{
+  locexpr_find_frame_base_location
+};
+
+/* Implement find_frame_base_location method for LOC_BLOCK functions using
+   DWARF location list for its DW_AT_frame_base.  */
+
+static void
+loclist_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
+				  const gdb_byte **start, size_t *length)
+{
+  struct dwarf2_loclist_baton *symbaton = SYMBOL_LOCATION_BATON (framefunc);
+
+  *start = dwarf2_find_location_expression (symbaton, length, pc);
+}
+
+/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
+   function uses DWARF location list for its DW_AT_frame_base.  */
+
+const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs =
+{
+  loclist_find_frame_base_location
+};
+
 static void
 dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
 			 const gdb_byte **start, size_t *length)
 {
-  if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
-    *length = 0;
-  else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
+  if (SYMBOL_BLOCK_OPS (framefunc) != NULL)
     {
-      struct dwarf2_loclist_baton *symbaton;
+      const struct symbol_block_ops *ops_block = SYMBOL_BLOCK_OPS (framefunc);
 
-      symbaton = SYMBOL_LOCATION_BATON (framefunc);
-      *start = dwarf2_find_location_expression (symbaton, length, pc);
+      ops_block->find_frame_base_location (framefunc, pc, start, length);
     }
   else
-    {
-      struct dwarf2_locexpr_baton *symbaton;
-
-      symbaton = SYMBOL_LOCATION_BATON (framefunc);
-      if (symbaton != NULL)
-	{
-	  *length = symbaton->size;
-	  *start = symbaton->data;
-	}
-      else
-	*length = 0;
-    }
+    *length = 0;
 
   if (*length == 0)
     error (_("Could not find the frame base for \"%s\"."),
@@ -3963,6 +3990,7 @@ const struct symbol_computed_ops dwarf2_locexpr_funcs = {
   locexpr_read_variable_at_entry,
   locexpr_read_needs_frame,
   locexpr_describe_location,
+  0,	/* location_has_loclist */
   locexpr_tracepoint_var_ref
 };
 
@@ -4141,6 +4169,7 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = {
   loclist_read_variable_at_entry,
   loclist_read_needs_frame,
   loclist_describe_location,
+  1,	/* location_has_loclist */
   loclist_tracepoint_var_ref
 };
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 36641b3..78448e6 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -133,6 +133,9 @@ struct dwarf2_loclist_baton
 extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
 extern const struct symbol_computed_ops dwarf2_loclist_funcs;
 
+extern const struct symbol_block_ops dwarf2_block_frame_base_locexpr_funcs;
+extern const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs;
+
 /* Compile a DWARF location expression to an agent expression.
    
    EXPR is the agent expression we are building.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 47e4958..9c99a88 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -92,6 +92,13 @@ static int use_deprecated_index_sections = 0;
 
 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;
@@ -1626,7 +1633,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,
@@ -6850,7 +6858,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);
@@ -9523,7 +9531,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;
 
@@ -11956,9 +11964,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
@@ -15725,7 +15732,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;
     }
 
@@ -15749,7 +15756,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));
@@ -15763,10 +15770,9 @@ 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)
+  if (SYMBOL_COMPUTED_OPS (sym)->location_has_loclist)
     cu->has_loclist = 1;
 }
 
@@ -15822,7 +15828,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
@@ -15865,13 +15871,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)
@@ -15892,7 +15898,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;
@@ -15967,7 +15973,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.  */
@@ -16005,7 +16011,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))
 		{
@@ -16052,7 +16058,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;
 
 	  {
@@ -16089,13 +16095,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;
@@ -16116,11 +16122,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_COMMON_BLOCK;
+	  SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK;
 	  SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
 	  add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
@@ -16327,19 +16333,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;
     }
 }
 
@@ -19060,7 +19065,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);
@@ -19083,7 +19088,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
@@ -19112,7 +19119,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;
     }
 }
@@ -20718,4 +20727,14 @@ 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);
+
+  dwarf2_locexpr_block_index = register_symbol_block_impl (LOC_BLOCK,
+					&dwarf2_block_frame_base_locexpr_funcs);
+  dwarf2_loclist_block_index = register_symbol_block_impl (LOC_BLOCK,
+					&dwarf2_block_frame_base_loclist_funcs);
 }
diff --git a/gdb/jit.c b/gdb/jit.c
index ecf7317..b5f6ff4 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -693,7 +693,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 48b5b3c..285aa06 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 2fed944..fd5b313 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -542,6 +542,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)
@@ -626,16 +631,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.  */
@@ -664,21 +666,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;
@@ -689,7 +689,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);
@@ -731,7 +731,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;
@@ -1056,7 +1056,7 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
 		  (enum_sym,
 		   obstack_copy0 (&mdebugread_objfile->objfile_obstack,
 				  f->name, strlen (f->name)));
-		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;
@@ -1089,7 +1089,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);
@@ -1145,7 +1145,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,
@@ -1285,7 +1285,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);
@@ -4119,7 +4119,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;
@@ -4940,4 +4940,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 cd8d06f..50e5822 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 a38ead1..a490bb4 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, obstack_copy0 (&objfile->objfile_obstack,
 				     name, pp - name));
@@ -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 e62293f..e27bc0d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -5037,9 +5037,111 @@ 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 function with frame base type.  ACLASS must be LOC_BLOCK.
+   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_block_impl (enum address_class aclass,
+			    const struct symbol_block_ops *ops)
+{
+  int result = next_aclass_value++;
+
+  gdb_assert (aclass == LOC_BLOCK);
+  gdb_assert (result < MAX_SYMBOL_IMPLS);
+  symbol_impl[result].aclass = aclass;
+  symbol_impl[result].ops_block = ops;
+
+  /* Sanity check OPS.  */
+  gdb_assert (ops != NULL);
+  gdb_assert (ops->find_frame_base_location != NULL);
+
+  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 7f0a4e6..354aa26 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -539,6 +539,9 @@ enum address_class
   /* The variable uses general_symbol_info->value->common_block field.
      It also always uses COMMON_BLOCK_DOMAIN.  */
   LOC_COMMON_BLOCK,
+
+  /* Not used, just notes the boundary of the enum.  */
+  LOC_FINAL_VALUE
 };
 
 /* The methods needed to implement LOC_COMPUTED.  These methods can
@@ -572,6 +575,9 @@ struct symbol_computed_ops
   void (*describe_location) (struct symbol * symbol, CORE_ADDR addr,
 			     struct ui_file * stream);
 
+  /* Non-zero if this symbol's address computation is dependent on PC.  */
+  unsigned char location_has_loclist;
+
   /* Tracepoint support.  Append bytecodes to the tracepoint agent
      expression AX that push the address of the object SYMBOL.  Set
      VALUE appropriately.  Note --- for objects in registers, this
@@ -583,6 +589,20 @@ struct symbol_computed_ops
 			      struct agent_expr *ax, struct axs_value *value);
 };
 
+/* The methods needed to implement LOC_BLOCK for inferior functions.
+   These methods can use the symbol's .aux_value for additional
+   per-symbol information.  */
+
+struct symbol_block_ops
+{
+  /* Fill in *START and *LENGTH with DWARF block data of function
+     FRAMEFUNC valid for inferior context address PC.  Set *LENGTH to
+     zero if such location is not valid for PC; *START is left
+     uninitialized in such case.  */
+  void (*find_frame_base_location) (struct symbol *framefunc, CORE_ADDR pc,
+				    const gdb_byte **start, size_t *length);
+};
+
 /* Functions used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
 
 struct symbol_register_ops
@@ -590,6 +610,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_BLOCK.  */
+  const struct symbol_block_ops *ops_block;
+
+  /* Used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
+  const struct symbol_register_ops *ops_register;
+};
+
+/* 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
@@ -612,15 +656,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.  */
 
@@ -645,18 +685,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.  */
@@ -675,9 +703,12 @@ 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_IMPL(symbol)		(symbol_impls[(symbol)->aclass_index])
+#define SYMBOL_ACLASS_INDEX(symbol)	(symbol)->aclass_index
+#define SYMBOL_CLASS(symbol)		(SYMBOL_IMPL (symbol).aclass)
 #define SYMBOL_IS_ARGUMENT(symbol)	(symbol)->is_argument
 #define SYMBOL_INLINED(symbol)		(symbol)->is_inlined
 #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \
@@ -685,10 +716,20 @@ 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_IMPL (symbol).ops_computed)
+#define SYMBOL_BLOCK_OPS(symbol)	(SYMBOL_IMPL (symbol).ops_block)
+#define SYMBOL_REGISTER_OPS(symbol)	(SYMBOL_IMPL (symbol).ops_register)
 #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_block_impl (enum address_class aclass,
+				       const struct symbol_block_ops *ops);
+
+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 896b817..e2b569e 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]