+\f
+
+/* 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;
+
+ /* Sanity check OPS. */
+ gdb_assert (ops != NULL);
+ gdb_assert (ops->tracepoint_var_ref != NULL);
+ gdb_assert (ops->describe_location != NULL);
+ gdb_assert (ops->read_needs_frame != NULL);
+ gdb_assert (ops->read_variable != NULL);
+
+ 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;
+}
+
+\f
+
+/* Initialize the symbol SYM. */
+
+void
+initialize_symbol (struct symbol *sym)
+{
+ memset (sym, 0, sizeof (*sym));
+ SYMBOL_SECTION (sym) = -1;
+}
+
+/* Allocate and initialize a new 'struct symbol' on OBJFILE's
+ obstack. */
+
+struct symbol *
+allocate_symbol (struct objfile *objfile)
+{
+ struct symbol *result;
+
+ result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
+ SYMBOL_SECTION (result) = -1;
+
+ return result;
+}
+
+/* Allocate and initialize a new 'struct template_symbol' on OBJFILE's
+ obstack. */
+
+struct template_symbol *
+allocate_template_symbol (struct objfile *objfile)
+{
+ struct template_symbol *result;
+
+ result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
+ SYMBOL_SECTION (&result->base) = -1;
+
+ return result;
+}
+
+\f
+