Look up primitive types as symbols.

gdb/ChangeLog:

	* 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.
This commit is contained in:
Doug Evans 2014-12-23 07:55:39 -08:00
parent 9d7b48dc6e
commit 1994afbf19
15 changed files with 411 additions and 63 deletions

View file

@ -1,3 +1,55 @@
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> 2014-12-23 Doug Evans <xdje42@gmail.com>
* symtab.h (SYMBOL_DOMAIN_BITS): New macro. * symtab.h (SYMBOL_DOMAIN_BITS): New macro.

View file

@ -3716,7 +3716,10 @@ See set/show multiple-symbol."));
(SYMBOL_CLASS (syms[i].sym) == LOC_CONST (SYMBOL_CLASS (syms[i].sym) == LOC_CONST
&& SYMBOL_TYPE (syms[i].sym) != NULL && SYMBOL_TYPE (syms[i].sym) != NULL
&& TYPE_CODE (SYMBOL_TYPE (syms[i].sym)) == TYPE_CODE_ENUM); && 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) if (SYMBOL_LINE (syms[i].sym) != 0 && symtab != NULL)
printf_unfiltered (_("[%d] %s at %s:%d\n"), printf_unfiltered (_("[%d] %s at %s:%d\n"),
@ -4466,6 +4469,11 @@ cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
char *copy; char *copy;
struct cache_entry *e; 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 /* 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 for that symbol depends on the context. To determine whether
the symbol is local or not, we check the block where we found it the symbol is local or not, we check the block where we found it

View file

@ -25,6 +25,7 @@
#include "cp-support.h" #include "cp-support.h"
#include "addrmap.h" #include "addrmap.h"
#include "gdbtypes.h" #include "gdbtypes.h"
#include "objfiles.h"
/* This is used by struct block to store namespace-related info for /* This is used by struct block to store namespace-related info for
C++ files, namely using declarations and the current namespace in C++ files, namely using declarations and the current namespace in
@ -39,6 +40,31 @@ struct block_namespace_info
static void block_initialize_namespace (struct block *block, static void block_initialize_namespace (struct block *block,
struct obstack *obstack); 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, /* Return Nonzero if block a is lexically nested within block b,
or if a and b have the same pc range. or if a and b have the same pc range.
Return zero otherwise. */ Return zero otherwise. */

View file

@ -136,6 +136,14 @@ struct blockvector
#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n] #define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n]
#define BLOCKVECTOR_MAP(blocklist) ((blocklist)->map) #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_linkage_function (const struct block *);
extern struct symbol *block_containing_function (const struct block *); extern struct symbol *block_containing_function (const struct block *);

View file

@ -2941,13 +2941,6 @@ classify_name (struct parser_state *par_state, const struct block *block,
return TYPENAME; 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. */ /* See if it's an ObjC classname. */
if (parse_language (par_state)->la_language == language_objc && !sym) if (parse_language (par_state)->la_language == language_objc && !sym)
{ {

View file

@ -242,12 +242,18 @@ cp_basic_lookup_symbol (const char *name, const struct block *block,
} }
/* Search bare symbol NAME in DOMAIN in BLOCK. /* 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 SEARCH is non-zero then see if we can determine "this" from BLOCK, and
if so then also search for NAME in that class. */ if so then also search for NAME in that class. */
static struct symbol * 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) const domain_enum domain, int search)
{ {
struct symbol *sym; struct symbol *sym;
@ -262,6 +268,25 @@ cp_lookup_bare_symbol (const char *name, const struct block *block,
if (sym != NULL) if (sym != NULL)
return sym; 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); sym = lookup_global_symbol (name, block, domain);
if (sym != NULL) if (sym != NULL)
return sym; return sym;
@ -378,7 +403,7 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
prefix_len = cp_entire_prefix_len (name); prefix_len = cp_entire_prefix_len (name);
if (prefix_len == 0) 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 /* This would be simpler if we just called cp_lookup_nested_symbol
at this point. But that would require first looking up the containing at this point. But that would require first looking up the containing
@ -753,7 +778,8 @@ cp_lookup_symbol_namespace (const char *scope,
"x". */ "x". */
static struct symbol * 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 struct block *block,
const domain_enum domain, const domain_enum domain,
const char *scope, const char *scope,
@ -775,14 +801,25 @@ lookup_namespace_scope (const char *name,
new_scope_len += 2; new_scope_len += 2;
} }
new_scope_len += cp_find_first_component (scope + new_scope_len); 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); scope, new_scope_len);
if (sym != NULL) if (sym != NULL)
return sym; return sym;
} }
/* Okay, we didn't find a match in our children, so look for the /* 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); namespace = alloca (scope_len + 1);
strncpy (namespace, scope, scope_len); strncpy (namespace, scope, scope_len);
@ -817,7 +854,7 @@ cp_lookup_symbol_nonlocal (const struct language_defn *langdef,
/* First, try to find the symbol in the given namespace, and all /* First, try to find the symbol in the given namespace, and all
containing namespaces. */ 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. */ /* Search for name in namespaces imported to this and parent blocks. */
if (sym == NULL) if (sym == NULL)

View file

@ -1306,14 +1306,11 @@ lookup_typename (const struct language_defn *language,
struct symbol *sym; struct symbol *sym;
struct type *type; 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) if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return SYMBOL_TYPE (sym); return SYMBOL_TYPE (sym);
type = language_lookup_primitive_type (language, gdbarch, name);
if (type)
return type;
if (noerr) if (noerr)
return NULL; return NULL;
error (_("No type named %s."), name); error (_("No type named %s."), name);

View file

@ -50,6 +50,13 @@ static SCM domain_keyword;
static SCM frame_keyword; static SCM frame_keyword;
static const struct objfile_data *syscm_objfile_data_key; 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;
};
/* Administrivia for symbol smobs. */ /* Administrivia for symbol smobs. */
@ -75,21 +82,45 @@ syscm_eq_symbol_smob (const void *ap, const void *bp)
&& a->symbol != NULL); && 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. /* Return the struct symbol pointer -> SCM mapping table.
It is created if necessary. */ It is created if necessary. */
static htab_t 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;
htab_t htab = objfile_data (objfile, syscm_objfile_data_key);
if (SYMBOL_OBJFILE_OWNED (symbol))
{
struct objfile *objfile = symbol_objfile (symbol);
htab = objfile_data (objfile, syscm_objfile_data_key);
if (htab == NULL) if (htab == NULL)
{ {
htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob, htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob,
syscm_eq_symbol_smob); syscm_eq_symbol_smob);
set_objfile_data (objfile, syscm_objfile_data_key, htab); 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; return htab;
} }
@ -103,7 +134,7 @@ syscm_free_symbol_smob (SCM self)
if (s_smob->symbol != NULL) 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); gdbscm_clear_eqable_gsmob_ptr_slot (htab, &s_smob->base);
} }
@ -181,7 +212,7 @@ syscm_scm_from_symbol (struct symbol *symbol)
/* If we've already created a gsmob for this symbol, return it. /* If we've already created a gsmob for this symbol, return it.
This makes symbols eq?-able. */ This makes symbols eq?-able. */
htab = syscm_objfile_symbol_map (symbol); htab = syscm_get_symbol_map (symbol);
s_smob_for_lookup.symbol = symbol; s_smob_for_lookup.symbol = symbol;
slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &s_smob_for_lookup.base); slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &s_smob_for_lookup.base);
if (*slot != NULL) if (*slot != NULL)
@ -319,8 +350,9 @@ gdbscm_symbol_type (SCM self)
return tyscm_scm_from_type (SYMBOL_TYPE (symbol)); return tyscm_scm_from_type (SYMBOL_TYPE (symbol));
} }
/* (symbol-symtab <gdb:symbol>) -> <gdb:symtab> /* (symbol-symtab <gdb:symbol>) -> <gdb:symtab> | #f
Return the symbol table of SELF. */ Return the symbol table of SELF.
If SELF does not have a symtab (it is arch-owned) return #f. */
static SCM static SCM
gdbscm_symbol_symtab (SCM self) gdbscm_symbol_symtab (SCM self)
@ -329,6 +361,8 @@ gdbscm_symbol_symtab (SCM self)
= syscm_get_valid_symbol_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); = syscm_get_valid_symbol_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
const struct symbol *symbol = s_smob->symbol; const struct symbol *symbol = s_smob->symbol;
if (!SYMBOL_OBJFILE_OWNED (symbol))
return SCM_BOOL_F;
return stscm_scm_from_symtab (symbol_symtab (symbol)); return stscm_scm_from_symtab (symbol_symtab (symbol));
} }
@ -761,4 +795,8 @@ gdbscm_initialize_symbols (void)
invalidate symbols when an object file is about to be deleted. */ invalidate symbols when an object file is about to be deleted. */
syscm_objfile_data_key syscm_objfile_data_key
= register_objfile_data_with_cleanup (NULL, syscm_del_objfile_symbols); = 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);
} }

View file

@ -987,6 +987,24 @@ language_bool_type (const struct language_defn *la,
return ld->arch_info[la->la_language].bool_type_default; 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 * struct type *
language_lookup_primitive_type (const struct language_defn *la, language_lookup_primitive_type (const struct language_defn *la,
struct gdbarch *gdbarch, struct gdbarch *gdbarch,
@ -994,33 +1012,113 @@ language_lookup_primitive_type (const struct language_defn *la,
{ {
struct language_gdbarch *ld = gdbarch_data (gdbarch, struct language_gdbarch *ld = gdbarch_data (gdbarch,
language_gdbarch_data); 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) if (symbol_lookup_debug)
{ {
fprintf_unfiltered (gdb_stdlog, 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); la->la_name, host_address_to_string (gdbarch), name);
} }
for (p = ld->arch_info[la->la_language].primitive_type_vector; typep = language_lookup_primitive_type_1 (lai, name);
(*p) != NULL; if (typep == NULL)
p++)
{ {
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) if (symbol_lookup_debug)
fprintf_unfiltered (gdb_stdlog, " = NULL\n"); fprintf_unfiltered (gdb_stdlog, " = NULL\n");
return (NULL); 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, " = %s\n", host_address_to_string (sym));
return sym;
} }
/* Initialize the language routines. */ /* Initialize the language routines. */

View file

@ -111,6 +111,11 @@ struct language_arch_info
expressions, regardless of whether the program being debugged expressions, regardless of whether the program being debugged
actually defines such a type. */ actually defines such a type. */
struct type **primitive_type_vector; 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. */ /* Type of elements of strings. */
struct type *string_char_type; struct type *string_char_type;
@ -436,10 +441,21 @@ struct type *language_bool_type (const struct language_defn *l,
struct type *language_string_char_type (const struct language_defn *l, struct type *language_string_char_type (const struct language_defn *l,
struct gdbarch *gdbarch); 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 type *language_lookup_primitive_type (const struct language_defn *l,
struct gdbarch *gdbarch, struct gdbarch *gdbarch,
const char *name); 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);
/* These macros define the behaviour of the expression /* These macros define the behaviour of the expression
evaluator. */ evaluator. */

View file

@ -1251,7 +1251,10 @@ address_info (char *exp, int from_tty)
current_language->la_language, DMGL_ANSI); current_language->la_language, DMGL_ANSI);
printf_filtered ("\" is "); printf_filtered ("\" is ");
val = SYMBOL_VALUE (sym); val = SYMBOL_VALUE (sym);
if (SYMBOL_OBJFILE_OWNED (sym))
section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym); section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym);
else
section = NULL;
gdbarch = symbol_arch (sym); gdbarch = symbol_arch (sym);
if (SYMBOL_COMPUTED_OPS (sym) != NULL) if (SYMBOL_COMPUTED_OPS (sym) != NULL)

View file

@ -87,6 +87,9 @@ sympy_get_symtab (PyObject *self, void *closure)
SYMPY_REQUIRE_VALID (self, symbol); SYMPY_REQUIRE_VALID (self, symbol);
if (!SYMBOL_OBJFILE_OWNED (symbol))
Py_RETURN_NONE;
return symtab_to_symtab_object (symbol_symtab (symbol)); return symtab_to_symtab_object (symbol_symtab (symbol));
} }
@ -290,7 +293,8 @@ set_symbol (symbol_object *obj, struct symbol *symbol)
{ {
obj->symbol = symbol; obj->symbol = symbol;
obj->prev = NULL; obj->prev = NULL;
if (symbol_symtab (symbol) != NULL) if (SYMBOL_OBJFILE_OWNED (symbol)
&& symbol_symtab (symbol) != NULL)
{ {
struct objfile *objfile = symbol_objfile (symbol); struct objfile *objfile = symbol_objfile (symbol);
@ -334,6 +338,7 @@ sympy_dealloc (PyObject *obj)
if (sym_obj->prev) if (sym_obj->prev)
sym_obj->prev->next = sym_obj->next; sym_obj->prev->next = sym_obj->next;
else if (sym_obj->symbol != NULL else if (sym_obj->symbol != NULL
&& SYMBOL_OBJFILE_OWNED (sym_obj->symbol)
&& symbol_symtab (sym_obj->symbol) != NULL) && symbol_symtab (sym_obj->symbol) != NULL)
{ {
set_objfile_data (symbol_objfile (sym_obj->symbol), set_objfile_data (symbol_objfile (sym_obj->symbol),

View file

@ -466,8 +466,12 @@ print_symbol (void *args)
struct symbol *symbol = ((struct print_symbol_args *) args)->symbol; struct symbol *symbol = ((struct print_symbol_args *) args)->symbol;
int depth = ((struct print_symbol_args *) args)->depth; int depth = ((struct print_symbol_args *) args)->depth;
struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile; struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile;
struct obj_section *section = SYMBOL_OBJ_SECTION (symbol_objfile (symbol), struct obj_section *section;
symbol);
if (SYMBOL_OBJFILE_OWNED (symbol))
section = SYMBOL_OBJ_SECTION (symbol_objfile (symbol), symbol);
else
section = NULL;
print_spaces (depth, outfile); print_spaces (depth, outfile);
if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN) if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN)

View file

@ -1150,6 +1150,9 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
if (!sym) if (!sym)
return NULL; return NULL;
if (!SYMBOL_OBJFILE_OWNED (sym))
return sym;
/* We either have an OBJFILE, or we can get at it from the sym's /* We either have an OBJFILE, or we can get at it from the sym's
symtab. Anything else is a bug. */ symtab. Anything else is a bug. */
gdb_assert (objfile || symbol_symtab (sym)); gdb_assert (objfile || symbol_symtab (sym));
@ -1421,6 +1424,13 @@ lookup_symbol_aux (const char *name, const struct block *block,
domain_name (domain), language_str (language)); 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 /* 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 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 certainly use it later. If we don't set it, the contents of
@ -1848,6 +1858,25 @@ basic_lookup_symbol_nonlocal (const struct language_defn *langdef,
if (sym != NULL) if (sym != NULL)
return sym; 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); return lookup_global_symbol (name, block, domain);
} }
@ -5313,13 +5342,23 @@ initialize_ordinary_address_classes (void)
/* 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 void
initialize_objfile_symbol (struct symbol *sym) initialize_objfile_symbol (struct symbol *sym)
{ {
memset (sym, 0, sizeof (*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 /* Allocate and initialize a new 'struct symbol' on OBJFILE's
@ -5331,7 +5370,7 @@ allocate_symbol (struct objfile *objfile)
struct symbol *result; struct symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol); result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
SYMBOL_SECTION (result) = -1; initialize_objfile_symbol_1 (result);
return result; return result;
} }
@ -5345,7 +5384,7 @@ allocate_template_symbol (struct objfile *objfile)
struct template_symbol *result; struct template_symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol); result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
SYMBOL_SECTION (&result->base) = -1; initialize_objfile_symbol_1 (&result->base);
return result; return result;
} }
@ -5355,7 +5394,8 @@ allocate_template_symbol (struct objfile *objfile)
struct objfile * struct objfile *
symbol_objfile (const struct symbol *symbol) 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. */ /* See symtab.h. */
@ -5363,7 +5403,9 @@ symbol_objfile (const struct symbol *symbol)
struct gdbarch * struct gdbarch *
symbol_arch (const struct symbol *symbol) 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. */ /* See symtab.h. */
@ -5371,7 +5413,8 @@ symbol_arch (const struct symbol *symbol)
struct symtab * struct symtab *
symbol_symtab (const struct symbol *symbol) symbol_symtab (const struct symbol *symbol)
{ {
return symbol->symtab; gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
return symbol->owner.symtab;
} }
/* See symtab.h. */ /* See symtab.h. */
@ -5379,7 +5422,8 @@ symbol_symtab (const struct symbol *symbol)
void void
symbol_set_symtab (struct symbol *symbol, struct symtab *symtab) symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
{ {
symbol->symtab = symtab; gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
symbol->owner.symtab = symtab;
} }

View file

@ -711,11 +711,20 @@ struct symbol
struct type *type; struct type *type;
/* The symbol table containing this symbol. This is the file /* The owner of this symbol.
associated with LINE. It can be NULL during symbols read-in but it is Which one to use is defined by symbol.is_arch_owned. */
never NULL during normal operation. */
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; struct symtab *symtab;
/* For types defined by the architecture. */
struct gdbarch *arch;
} owner;
/* Domain code. */ /* Domain code. */
ENUM_BITFIELD(domain_enum_tag) domain : SYMBOL_DOMAIN_BITS; ENUM_BITFIELD(domain_enum_tag) domain : SYMBOL_DOMAIN_BITS;
@ -726,6 +735,11 @@ struct symbol
unsigned int aclass_index : SYMBOL_ACLASS_BITS; 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. */ /* Whether this is an argument. */
unsigned is_argument : 1; unsigned is_argument : 1;
@ -742,6 +756,7 @@ struct symbol
SYMBOL_INLINED set) this is the line number of the function's call SYMBOL_INLINED set) this is the line number of the function's call
site. Inlined function symbols are not definitions, and they are site. Inlined function symbols are not definitions, and they are
never found by symbol table lookup. 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 FIXME: Should we really make the assumption that nobody will try
to debug files longer than 64K lines? What about machine to debug files longer than 64K lines? What about machine
@ -769,10 +784,14 @@ struct symbol
extern const struct symbol_impl *symbol_impls; 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_DOMAIN(symbol) (symbol)->domain
#define SYMBOL_IMPL(symbol) (symbol_impls[(symbol)->aclass_index]) #define SYMBOL_IMPL(symbol) (symbol_impls[(symbol)->aclass_index])
#define SYMBOL_ACLASS_INDEX(symbol) (symbol)->aclass_index #define SYMBOL_ACLASS_INDEX(symbol) (symbol)->aclass_index
#define SYMBOL_CLASS(symbol) (SYMBOL_IMPL (symbol).aclass) #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_IS_ARGUMENT(symbol) (symbol)->is_argument
#define SYMBOL_INLINED(symbol) (symbol)->is_inlined #define SYMBOL_INLINED(symbol) (symbol)->is_inlined
#define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \ #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \