+2014-12-23 Doug Evans <xdje42@gmail.com>
+
+ * ada-lang.c (user_select_syms): Only fetch symtab if symbol is
+ objfile-owned.
+ (cache_symbol): Ignore symbols that are not objfile-owned.
+ * block.c (block_objfile): New function.
+ (block_gdbarch): New function.
+ * block.h (block_objfile): Declare.
+ (block_gdbarch): Declare.
+ * c-exp.y (classify_name): Remove call to
+ language_lookup_primitive_type. No longer necessary.
+ * gdbtypes.c (lookup_typename): Call lookup_symbol_in_language.
+ Remove call to language_lookup_primitive_type. No longer necessary.
+ * guile/scm-symbol.c (syscm_gdbarch_data_key): New static global.
+ (syscm_gdbarch_data): New struct.
+ (syscm_init_arch_symbols): New function.
+ (syscm_get_symbol_map): Renamed from syscm_objfile_symbol_map.
+ All callers updated. Handle symbols owned by arches.
+ (gdbscm_symbol_symtab): Handle symbols owned by arches.
+ (gdbscm_initialize_symbols): Initialize syscm_gdbarch_data_key.
+ * language.c (language_lookup_primitive_type_1): New function.
+ (language_lookup_primitive_type): Call it.
+ (language_alloc_type_symbol): New function.
+ (language_init_primitive_type_symbols): New function.
+ (language_lookup_primitive_type_as_symbol): New function.
+ * language.h (struct language_arch_info) <primitive_type_symbols>:
+ New member.
+ (language_lookup_primitive_type): Add function comment.
+ (language_lookup_primitive_type_as_symbol): Declare.
+ * printcmd.c (address_info): Handle arch-owned symbols.
+ * python/py-symbol.c (sympy_get_symtab): Ditto.
+ (set_symbol): Ditto.
+ (sympy_dealloc): Ditto.
+ * symmisc.c (print_symbol): Ditto.
+ * symtab.c (fixup_symbol_section): Ditto.
+ (lookup_symbol_aux): Initialize block_found.
+ (basic_lookup_symbol_nonlocal): Try looking up the symbol as a
+ primitive type.
+ (initialize_objfile_symbol_1): New function.
+ (initialize_objfile_symbol): Call it.
+ (allocate_symbol): Call it.
+ (allocate_template_symbol): Call it.
+ (symbol_objfile): Assert symbol is objfile-owned.
+ (symbol_arch, symbol_symtab, symbol_set_symtab): Ditto.
+ * symtab.h (struct symbol) <owner>: Replaces member "symtab".
+ (struct symbol) <is_objfile_owned>: New member.
+ (SYMBOL_OBJFILE_OWNED): New macro.
+ * cp-namespace.c (cp_lookup_bare_symbol): New arg langdef.
+ All callers updated. Try to find the symbol as a primitive type.
+ (lookup_namespace_scope): New arg langdef. All callers updated.
+ Call cp_lookup_bare_symbol directly for simple bare symbols.
+
2014-12-23 Doug Evans <xdje42@gmail.com>
* symtab.h (SYMBOL_DOMAIN_BITS): New macro.
(SYMBOL_CLASS (syms[i].sym) == LOC_CONST
&& SYMBOL_TYPE (syms[i].sym) != NULL
&& TYPE_CODE (SYMBOL_TYPE (syms[i].sym)) == TYPE_CODE_ENUM);
- struct symtab *symtab = symbol_symtab (syms[i].sym);
+ struct symtab *symtab = NULL;
+
+ if (SYMBOL_OBJFILE_OWNED (syms[i].sym))
+ symtab = symbol_symtab (syms[i].sym);
if (SYMBOL_LINE (syms[i].sym) != 0 && symtab != NULL)
printf_unfiltered (_("[%d] %s at %s:%d\n"),
char *copy;
struct cache_entry *e;
+ /* Symbols for builtin types don't have a block.
+ For now don't cache such symbols. */
+ if (sym != NULL && !SYMBOL_OBJFILE_OWNED (sym))
+ return;
+
/* If the symbol is a local symbol, then do not cache it, as a search
for that symbol depends on the context. To determine whether
the symbol is local or not, we check the block where we found it
#include "cp-support.h"
#include "addrmap.h"
#include "gdbtypes.h"
+#include "objfiles.h"
/* This is used by struct block to store namespace-related info for
C++ files, namely using declarations and the current namespace in
static void block_initialize_namespace (struct block *block,
struct obstack *obstack);
+/* See block.h. */
+
+struct objfile *
+block_objfile (const struct block *block)
+{
+ const struct global_block *global_block;
+
+ if (BLOCK_FUNCTION (block) != NULL)
+ return symbol_objfile (BLOCK_FUNCTION (block));
+
+ global_block = (struct global_block *) block_global_block (block);
+ return COMPUNIT_OBJFILE (global_block->compunit_symtab);
+}
+
+/* See block. */
+
+struct gdbarch *
+block_gdbarch (const struct block *block)
+{
+ if (BLOCK_FUNCTION (block) != NULL)
+ return symbol_arch (BLOCK_FUNCTION (block));
+
+ return get_objfile_arch (block_objfile (block));
+}
+
/* Return Nonzero if block a is lexically nested within block b,
or if a and b have the same pc range.
Return zero otherwise. */
#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n]
#define BLOCKVECTOR_MAP(blocklist) ((blocklist)->map)
+/* Return the objfile of BLOCK, which must be non-NULL. */
+
+extern struct objfile *block_objfile (const struct block *block);
+
+/* Return the architecture of BLOCK, which must be non-NULL. */
+
+extern struct gdbarch *block_gdbarch (const struct block *block);
+
extern struct symbol *block_linkage_function (const struct block *);
extern struct symbol *block_containing_function (const struct block *);
return TYPENAME;
}
- yylval.tsym.type
- = language_lookup_primitive_type (parse_language (par_state),
- parse_gdbarch (par_state),
- copy);
- if (yylval.tsym.type != NULL)
- return TYPENAME;
-
/* See if it's an ObjC classname. */
if (parse_language (par_state)->la_language == language_objc && !sym)
{
}
/* Search bare symbol NAME in DOMAIN in BLOCK.
- NAME is guaranteed to not have any scope (no "::").
+ NAME is guaranteed to not have any scope (no "::") in its name, though
+ if for example NAME is a template spec then "::" may appear in the
+ argument list.
+ If LANGDEF is non-NULL then try to lookup NAME as a primitive type in
+ that language. Normally we wouldn't need LANGDEF but fortran also uses
+ this code.
If SEARCH is non-zero then see if we can determine "this" from BLOCK, and
if so then also search for NAME in that class. */
static struct symbol *
-cp_lookup_bare_symbol (const char *name, const struct block *block,
+cp_lookup_bare_symbol (const struct language_defn *langdef,
+ const char *name, const struct block *block,
const domain_enum domain, int search)
{
struct symbol *sym;
if (sym != NULL)
return sym;
+ /* If we didn't find a definition for a builtin type in the static block,
+ search for it now. This is actually the right thing to do and can be
+ a massive performance win. E.g., when debugging a program with lots of
+ shared libraries we could search all of them only to find out the
+ builtin type isn't defined in any of them. This is common for types
+ like "void". */
+ if (langdef != NULL && domain == VAR_DOMAIN)
+ {
+ struct gdbarch *gdbarch;
+
+ if (block == NULL)
+ gdbarch = target_gdbarch ();
+ else
+ gdbarch = block_gdbarch (block);
+ sym = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name);
+ if (sym != NULL)
+ return sym;
+ }
+
sym = lookup_global_symbol (name, block, domain);
if (sym != NULL)
return sym;
prefix_len = cp_entire_prefix_len (name);
if (prefix_len == 0)
- return cp_lookup_bare_symbol (name, block, domain, search);
+ return cp_lookup_bare_symbol (NULL, name, block, domain, search);
/* This would be simpler if we just called cp_lookup_nested_symbol
at this point. But that would require first looking up the containing
"x". */
static struct symbol *
-lookup_namespace_scope (const char *name,
+lookup_namespace_scope (const struct language_defn *langdef,
+ const char *name,
const struct block *block,
const domain_enum domain,
const char *scope,
new_scope_len += 2;
}
new_scope_len += cp_find_first_component (scope + new_scope_len);
- sym = lookup_namespace_scope (name, block, domain,
+ sym = lookup_namespace_scope (langdef, name, block, domain,
scope, new_scope_len);
if (sym != NULL)
return sym;
}
/* Okay, we didn't find a match in our children, so look for the
- name in the current namespace. */
+ name in the current namespace.
+
+ If we there is no scope and we know we have a bare symbol, then short
+ circuit everything and call cp_lookup_bare_symbol directly.
+ This isn't an optimization, rather it allows us to pass LANGDEF which
+ is needed for primitive type lookup. The test doesn't have to be
+ perfect: if NAME is a bare symbol that our test doesn't catch (e.g., a
+ template symbol with "::" in the argument list) then
+ cp_lookup_symbol_in_namespace will catch it. */
+
+ if (scope_len == 0 && strchr (name, ':') == NULL)
+ return cp_lookup_bare_symbol (langdef, name, block, domain, 1);
namespace = alloca (scope_len + 1);
strncpy (namespace, scope, scope_len);
/* First, try to find the symbol in the given namespace, and all
containing namespaces. */
- sym = lookup_namespace_scope (name, block, domain, scope, 0);
+ sym = lookup_namespace_scope (langdef, name, block, domain, scope, 0);
/* Search for name in namespaces imported to this and parent blocks. */
if (sym == NULL)
struct symbol *sym;
struct type *type;
- sym = lookup_symbol (name, block, VAR_DOMAIN, 0);
+ sym = lookup_symbol_in_language (name, block, VAR_DOMAIN,
+ language->la_language, NULL);
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return SYMBOL_TYPE (sym);
- type = language_lookup_primitive_type (language, gdbarch, name);
- if (type)
- return type;
-
if (noerr)
return NULL;
error (_("No type named %s."), name);
static SCM frame_keyword;
static const struct objfile_data *syscm_objfile_data_key;
+static struct gdbarch_data *syscm_gdbarch_data_key;
+
+struct syscm_gdbarch_data
+{
+ /* Hash table to implement eqable gdbarch symbols. */
+ htab_t htab;
+};
\f
/* Administrivia for symbol smobs. */
&& a->symbol != NULL);
}
+static void *
+syscm_init_arch_symbols (struct gdbarch *gdbarch)
+{
+ struct syscm_gdbarch_data *data
+ = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct syscm_gdbarch_data);
+
+ data->htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob,
+ syscm_eq_symbol_smob);
+ return data;
+}
+
/* Return the struct symbol pointer -> SCM mapping table.
It is created if necessary. */
static htab_t
-syscm_objfile_symbol_map (struct symbol *symbol)
+syscm_get_symbol_map (struct symbol *symbol)
{
- struct objfile *objfile = symbol_objfile (symbol);
- htab_t htab = objfile_data (objfile, syscm_objfile_data_key);
+ htab_t htab;
- if (htab == NULL)
+ if (SYMBOL_OBJFILE_OWNED (symbol))
{
- htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob,
- syscm_eq_symbol_smob);
- set_objfile_data (objfile, syscm_objfile_data_key, htab);
+ struct objfile *objfile = symbol_objfile (symbol);
+
+ htab = objfile_data (objfile, syscm_objfile_data_key);
+ if (htab == NULL)
+ {
+ htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob,
+ syscm_eq_symbol_smob);
+ set_objfile_data (objfile, syscm_objfile_data_key, htab);
+ }
+ }
+ else
+ {
+ struct gdbarch *gdbarch = symbol_arch (symbol);
+ struct syscm_gdbarch_data *data = gdbarch_data (gdbarch,
+ syscm_gdbarch_data_key);
+
+ htab = data->htab;
}
return htab;
if (s_smob->symbol != NULL)
{
- htab_t htab = syscm_objfile_symbol_map (s_smob->symbol);
+ htab_t htab = syscm_get_symbol_map (s_smob->symbol);
gdbscm_clear_eqable_gsmob_ptr_slot (htab, &s_smob->base);
}
/* If we've already created a gsmob for this symbol, return it.
This makes symbols eq?-able. */
- htab = syscm_objfile_symbol_map (symbol);
+ htab = syscm_get_symbol_map (symbol);
s_smob_for_lookup.symbol = symbol;
slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &s_smob_for_lookup.base);
if (*slot != NULL)
return tyscm_scm_from_type (SYMBOL_TYPE (symbol));
}
-/* (symbol-symtab <gdb:symbol>) -> <gdb:symtab>
- Return the symbol table of SELF. */
+/* (symbol-symtab <gdb:symbol>) -> <gdb:symtab> | #f
+ Return the symbol table of SELF.
+ If SELF does not have a symtab (it is arch-owned) return #f. */
static SCM
gdbscm_symbol_symtab (SCM self)
= syscm_get_valid_symbol_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
const struct symbol *symbol = s_smob->symbol;
+ if (!SYMBOL_OBJFILE_OWNED (symbol))
+ return SCM_BOOL_F;
return stscm_scm_from_symtab (symbol_symtab (symbol));
}
invalidate symbols when an object file is about to be deleted. */
syscm_objfile_data_key
= register_objfile_data_with_cleanup (NULL, syscm_del_objfile_symbols);
+
+ /* Arch-specific symbol data. */
+ syscm_gdbarch_data_key
+ = gdbarch_data_register_post_init (syscm_init_arch_symbols);
}
return ld->arch_info[la->la_language].bool_type_default;
}
+/* Helper function for primitive type lookup. */
+
+static struct type **
+language_lookup_primitive_type_1 (const struct language_arch_info *lai,
+ const char *name)
+{
+ struct type **p;
+
+ for (p = lai->primitive_type_vector; (*p) != NULL; p++)
+ {
+ if (strcmp (TYPE_NAME (*p), name) == 0)
+ return p;
+ }
+ return NULL;
+}
+
+/* See language.h. */
+
struct type *
language_lookup_primitive_type (const struct language_defn *la,
struct gdbarch *gdbarch,
{
struct language_gdbarch *ld = gdbarch_data (gdbarch,
language_gdbarch_data);
- struct type *const *p;
+ struct type **typep;
+
+ typep = language_lookup_primitive_type_1 (&ld->arch_info[la->la_language],
+ name);
+ if (typep == NULL)
+ return NULL;
+ return *typep;
+}
+
+/* Helper function for type lookup as a symbol.
+ Create the symbol corresponding to type TYPE in language LANG. */
+
+static struct symbol *
+language_alloc_type_symbol (enum language lang, struct type *type)
+{
+ struct symbol *symbol;
+ struct gdbarch *gdbarch;
+
+ gdb_assert (!TYPE_OBJFILE_OWNED (type));
+
+ gdbarch = TYPE_OWNER (type).gdbarch;
+ symbol = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct symbol);
+
+ symbol->ginfo.name = TYPE_NAME (type);
+ symbol->ginfo.language = lang;
+ symbol->owner.arch = gdbarch;
+ SYMBOL_OBJFILE_OWNED (symbol) = 0;
+ SYMBOL_TYPE (symbol) = type;
+ SYMBOL_DOMAIN (symbol) = VAR_DOMAIN;
+ SYMBOL_ACLASS_INDEX (symbol) = LOC_TYPEDEF;
+
+ return symbol;
+}
+
+/* Initialize the primitive type symbols of language LD.
+ The primitive type vector must have already been initialized. */
+
+static void
+language_init_primitive_type_symbols (struct language_arch_info *lai,
+ const struct language_defn *la,
+ struct gdbarch *gdbarch)
+{
+ int n;
+ struct compunit_symtab *cust;
+ struct symtab *symtab;
+ struct block *static_block, *global_block;
+
+ gdb_assert (lai->primitive_type_vector != NULL);
+
+ for (n = 0; lai->primitive_type_vector[n] != NULL; ++n)
+ continue;
+
+ lai->primitive_type_symbols
+ = GDBARCH_OBSTACK_CALLOC (gdbarch, n + 1, struct symbol *);
+
+ for (n = 0; lai->primitive_type_vector[n] != NULL; ++n)
+ {
+ lai->primitive_type_symbols[n]
+ = language_alloc_type_symbol (la->la_language,
+ lai->primitive_type_vector[n]);
+ }
+
+ /* Note: The result of symbol lookup is normally a symbol *and* the block
+ it was found in (returned in global block_found). Builtin types don't
+ live in blocks. We *could* give them one, but there is no current need
+ so to keep things simple symbol lookup is extended to allow for
+ BLOCK_FOUND to be NULL. */
+}
+
+/* See language.h. */
+
+struct symbol *
+language_lookup_primitive_type_as_symbol (const struct language_defn *la,
+ struct gdbarch *gdbarch,
+ const char *name)
+{
+ struct language_gdbarch *ld = gdbarch_data (gdbarch,
+ language_gdbarch_data);
+ struct language_arch_info *lai = &ld->arch_info[la->la_language];
+ struct type **typep;
+ struct symbol *sym;
if (symbol_lookup_debug)
{
fprintf_unfiltered (gdb_stdlog,
- "language_lookup_primitive_type (%s, %s, %s)",
+ "language_lookup_primitive_type_as_symbol"
+ " (%s, %s, %s)",
la->la_name, host_address_to_string (gdbarch), name);
}
- for (p = ld->arch_info[la->la_language].primitive_type_vector;
- (*p) != NULL;
- p++)
+ typep = language_lookup_primitive_type_1 (lai, name);
+ if (typep == NULL)
{
- if (strcmp (TYPE_NAME (*p), name) == 0)
- {
- if (symbol_lookup_debug)
- {
- fprintf_unfiltered (gdb_stdlog, " = %s\n",
- host_address_to_string (*p));
- }
- return (*p);
- }
+ if (symbol_lookup_debug)
+ fprintf_unfiltered (gdb_stdlog, " = NULL\n");
+ return NULL;
}
+ /* The set of symbols is lazily initialized. */
+ if (lai->primitive_type_symbols == NULL)
+ language_init_primitive_type_symbols (lai, la, gdbarch);
+
+ sym = lai->primitive_type_symbols[typep - lai->primitive_type_vector];
+
if (symbol_lookup_debug)
- fprintf_unfiltered (gdb_stdlog, " = NULL\n");
- return (NULL);
+ fprintf_unfiltered (gdb_stdlog, " = %s\n", host_address_to_string (sym));
+ return sym;
}
/* Initialize the language routines. */
expressions, regardless of whether the program being debugged
actually defines such a type. */
struct type **primitive_type_vector;
+
+ /* Symbol wrappers around primitive_type_vector, so that the symbol lookup
+ machinery can return them. */
+ struct symbol **primitive_type_symbols;
+
/* Type of elements of strings. */
struct type *string_char_type;
struct type *language_string_char_type (const struct language_defn *l,
struct gdbarch *gdbarch);
+/* Look up type NAME in language L, and return its definition for architecture
+ GDBARCH. Returns NULL if not found. */
+
struct type *language_lookup_primitive_type (const struct language_defn *l,
struct gdbarch *gdbarch,
const char *name);
+/* Wrapper around language_lookup_primitive_type to return the
+ corresponding symbol. */
+
+struct symbol *
+ language_lookup_primitive_type_as_symbol (const struct language_defn *l,
+ struct gdbarch *gdbarch,
+ const char *name);
+
\f
/* These macros define the behaviour of the expression
evaluator. */
current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is ");
val = SYMBOL_VALUE (sym);
- section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym);
+ if (SYMBOL_OBJFILE_OWNED (sym))
+ section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym);
+ else
+ section = NULL;
gdbarch = symbol_arch (sym);
if (SYMBOL_COMPUTED_OPS (sym) != NULL)
SYMPY_REQUIRE_VALID (self, symbol);
+ if (!SYMBOL_OBJFILE_OWNED (symbol))
+ Py_RETURN_NONE;
+
return symtab_to_symtab_object (symbol_symtab (symbol));
}
{
obj->symbol = symbol;
obj->prev = NULL;
- if (symbol_symtab (symbol) != NULL)
+ if (SYMBOL_OBJFILE_OWNED (symbol)
+ && symbol_symtab (symbol) != NULL)
{
struct objfile *objfile = symbol_objfile (symbol);
if (sym_obj->prev)
sym_obj->prev->next = sym_obj->next;
else if (sym_obj->symbol != NULL
+ && SYMBOL_OBJFILE_OWNED (sym_obj->symbol)
&& symbol_symtab (sym_obj->symbol) != NULL)
{
set_objfile_data (symbol_objfile (sym_obj->symbol),
struct symbol *symbol = ((struct print_symbol_args *) args)->symbol;
int depth = ((struct print_symbol_args *) args)->depth;
struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile;
- struct obj_section *section = SYMBOL_OBJ_SECTION (symbol_objfile (symbol),
- symbol);
+ struct obj_section *section;
+
+ if (SYMBOL_OBJFILE_OWNED (symbol))
+ section = SYMBOL_OBJ_SECTION (symbol_objfile (symbol), symbol);
+ else
+ section = NULL;
print_spaces (depth, outfile);
if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN)
if (!sym)
return NULL;
+ if (!SYMBOL_OBJFILE_OWNED (sym))
+ return sym;
+
/* We either have an OBJFILE, or we can get at it from the sym's
symtab. Anything else is a bug. */
gdb_assert (objfile || symbol_symtab (sym));
domain_name (domain), language_str (language));
}
+ /* Initialize block_found so that the language la_lookup_symbol_nonlocal
+ routines don't have to set it (to NULL) if a primitive type is found.
+ We do this early so that block_found is also NULL if no symbol is
+ found (though this is not part of the API, and callers cannot assume
+ this). */
+ block_found = NULL;
+
/* Make sure we do something sensible with is_a_field_of_this, since
the callers that set this parameter to some non-null value will
certainly use it later. If we don't set it, the contents of
if (sym != NULL)
return sym;
+ /* If we didn't find a definition for a builtin type in the static block,
+ search for it now. This is actually the right thing to do and can be
+ a massive performance win. E.g., when debugging a program with lots of
+ shared libraries we could search all of them only to find out the
+ builtin type isn't defined in any of them. This is common for types
+ like "void". */
+ if (domain == VAR_DOMAIN)
+ {
+ struct gdbarch *gdbarch;
+
+ if (block == NULL)
+ gdbarch = target_gdbarch ();
+ else
+ gdbarch = block_gdbarch (block);
+ sym = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name);
+ if (sym != NULL)
+ return sym;
+ }
+
return lookup_global_symbol (name, block, domain);
}
\f
-/* Initialize the symbol SYM. */
+/* Helper function to initialize the fields of an objfile-owned symbol.
+ It assumed that *SYM is already all zeroes. */
+
+static void
+initialize_objfile_symbol_1 (struct symbol *sym)
+{
+ SYMBOL_OBJFILE_OWNED (sym) = 1;
+ SYMBOL_SECTION (sym) = -1;
+}
+
+/* Initialize the symbol SYM, and mark it as being owned by an objfile. */
void
initialize_objfile_symbol (struct symbol *sym)
{
memset (sym, 0, sizeof (*sym));
- SYMBOL_SECTION (sym) = -1;
+ initialize_objfile_symbol_1 (sym);
}
/* Allocate and initialize a new 'struct symbol' on OBJFILE's
struct symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
- SYMBOL_SECTION (result) = -1;
+ initialize_objfile_symbol_1 (result);
return result;
}
struct template_symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
- SYMBOL_SECTION (&result->base) = -1;
+ initialize_objfile_symbol_1 (&result->base);
return result;
}
struct objfile *
symbol_objfile (const struct symbol *symbol)
{
- return SYMTAB_OBJFILE (symbol->symtab);
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ return SYMTAB_OBJFILE (symbol->owner.symtab);
}
/* See symtab.h. */
struct gdbarch *
symbol_arch (const struct symbol *symbol)
{
- return get_objfile_arch (symbol_objfile (symbol));
+ if (!SYMBOL_OBJFILE_OWNED (symbol))
+ return symbol->owner.arch;
+ return get_objfile_arch (SYMTAB_OBJFILE (symbol->owner.symtab));
}
/* See symtab.h. */
struct symtab *
symbol_symtab (const struct symbol *symbol)
{
- return symbol->symtab;
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ return symbol->owner.symtab;
}
/* See symtab.h. */
void
symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
{
- symbol->symtab = symtab;
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ symbol->owner.symtab = symtab;
}
\f
struct type *type;
- /* The symbol table containing this symbol. This is the file
- associated with LINE. It can be NULL during symbols read-in but it is
- never NULL during normal operation. */
- struct symtab *symtab;
+ /* The owner of this symbol.
+ Which one to use is defined by symbol.is_arch_owned. */
+
+ union
+ {
+ /* The symbol table containing this symbol. This is the file associated
+ with LINE. It can be NULL during symbols read-in but it is never NULL
+ during normal operation. */
+ struct symtab *symtab;
+
+ /* For types defined by the architecture. */
+ struct gdbarch *arch;
+ } owner;
/* Domain code. */
unsigned int aclass_index : SYMBOL_ACLASS_BITS;
+ /* If non-zero then symbol is objfile-owned, use owner.symtab.
+ Otherwise symbol is arch-owned, use owner.arch. */
+
+ unsigned int is_objfile_owned : 1;
+
/* Whether this is an argument. */
unsigned is_argument : 1;
SYMBOL_INLINED set) this is the line number of the function's call
site. Inlined function symbols are not definitions, and they are
never found by symbol table lookup.
+ If this symbol is arch-owned, LINE shall be zero.
FIXME: Should we really make the assumption that nobody will try
to debug files longer than 64K lines? What about machine
extern const struct symbol_impl *symbol_impls;
+/* Note: There is no accessor macro for symbol.owner because it is
+ "private". */
+
#define SYMBOL_DOMAIN(symbol) (symbol)->domain
#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_OBJFILE_OWNED(symbol) ((symbol)->is_objfile_owned)
#define SYMBOL_IS_ARGUMENT(symbol) (symbol)->is_argument
#define SYMBOL_INLINED(symbol) (symbol)->is_inlined
#define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \