aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <xdje42@gmail.com>2014-12-23 07:55:39 -0800
committerDoug Evans <xdje42@gmail.com>2014-12-23 07:58:14 -0800
commit1994afbf19892c9e614a034fbf1a5233e9addce3 (patch)
treeaf1c6640f99921a6f636e860dc10914dc53cedea
parent9d7b48dc6e8415e95f5228a6f66b414827eb0204 (diff)
downloadgdb-1994afbf19892c9e614a034fbf1a5233e9addce3.zip
gdb-1994afbf19892c9e614a034fbf1a5233e9addce3.tar.gz
gdb-1994afbf19892c9e614a034fbf1a5233e9addce3.tar.bz2
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.
-rw-r--r--gdb/ChangeLog52
-rw-r--r--gdb/ada-lang.c10
-rw-r--r--gdb/block.c26
-rw-r--r--gdb/block.h8
-rw-r--r--gdb/c-exp.y7
-rw-r--r--gdb/cp-namespace.c51
-rw-r--r--gdb/gdbtypes.c7
-rw-r--r--gdb/guile/scm-symbol.c60
-rw-r--r--gdb/language.c130
-rw-r--r--gdb/language.h16
-rw-r--r--gdb/printcmd.c5
-rw-r--r--gdb/python/py-symbol.c7
-rw-r--r--gdb/symmisc.c8
-rw-r--r--gdb/symtab.c60
-rw-r--r--gdb/symtab.h27
15 files changed, 411 insertions, 63 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index acf692f..dc1cb15 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,57 @@
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.
(struct symbol) <domain>: Use it.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 5d4ea2f..5d5d613 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -3716,7 +3716,10 @@ See set/show multiple-symbol."));
(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"),
@@ -4466,6 +4469,11 @@ cache_symbol (const char *name, domain_enum namespace, struct symbol *sym,
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
diff --git a/gdb/block.c b/gdb/block.c
index e791c73..8d45b6e 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -25,6 +25,7 @@
#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
@@ -39,6 +40,31 @@ struct block_namespace_info
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. */
diff --git a/gdb/block.h b/gdb/block.h
index 409a5c7..e6c5feb 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -136,6 +136,14 @@ struct blockvector
#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 *);
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 707e504..91728ee 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -2941,13 +2941,6 @@ classify_name (struct parser_state *par_state, const struct block *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)
{
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 6599d45..9e9dce0 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -242,12 +242,18 @@ cp_basic_lookup_symbol (const char *name, const struct block *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 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;
@@ -262,6 +268,25 @@ cp_lookup_bare_symbol (const char *name, const struct block *block,
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;
@@ -378,7 +403,7 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
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
@@ -753,7 +778,8 @@ cp_lookup_symbol_namespace (const char *scope,
"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,
@@ -775,14 +801,25 @@ lookup_namespace_scope (const char *name,
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);
@@ -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
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)
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 0048f6a..0297243 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1306,14 +1306,11 @@ lookup_typename (const struct language_defn *language,
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);
diff --git a/gdb/guile/scm-symbol.c b/gdb/guile/scm-symbol.c
index 6a19648..a627f94 100644
--- a/gdb/guile/scm-symbol.c
+++ b/gdb/guile/scm-symbol.c
@@ -50,6 +50,13 @@ static SCM domain_keyword;
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;
+};
/* Administrivia for symbol smobs. */
@@ -75,20 +82,44 @@ syscm_eq_symbol_smob (const void *ap, const void *bp)
&& 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;
@@ -103,7 +134,7 @@ syscm_free_symbol_smob (SCM self)
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);
}
@@ -181,7 +212,7 @@ syscm_scm_from_symbol (struct symbol *symbol)
/* 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)
@@ -319,8 +350,9 @@ gdbscm_symbol_type (SCM self)
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)
@@ -329,6 +361,8 @@ 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));
}
@@ -761,4 +795,8 @@ gdbscm_initialize_symbols (void)
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);
}
diff --git a/gdb/language.c b/gdb/language.c
index df45ddd..fa43857 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -987,6 +987,24 @@ language_bool_type (const struct language_defn *la,
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,
@@ -994,33 +1012,113 @@ language_lookup_primitive_type (const struct language_defn *la,
{
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. */
diff --git a/gdb/language.h b/gdb/language.h
index 2a47e64..1103fe9 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -111,6 +111,11 @@ struct language_arch_info
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;
@@ -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 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);
+
/* These macros define the behaviour of the expression
evaluator. */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 58b7ac0..020a47c 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1251,7 +1251,10 @@ address_info (char *exp, int from_tty)
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)
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 62fde64..fdff53f 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -87,6 +87,9 @@ sympy_get_symtab (PyObject *self, void *closure)
SYMPY_REQUIRE_VALID (self, symbol);
+ if (!SYMBOL_OBJFILE_OWNED (symbol))
+ Py_RETURN_NONE;
+
return symtab_to_symtab_object (symbol_symtab (symbol));
}
@@ -290,7 +293,8 @@ set_symbol (symbol_object *obj, struct symbol *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);
@@ -334,6 +338,7 @@ sympy_dealloc (PyObject *obj)
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),
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 3b6639d..9ae0847 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -466,8 +466,12 @@ print_symbol (void *args)
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)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e7cd5af..0efd9d2 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1150,6 +1150,9 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
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));
@@ -1421,6 +1424,13 @@ lookup_symbol_aux (const char *name, const struct block *block,
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
@@ -1848,6 +1858,25 @@ basic_lookup_symbol_nonlocal (const struct language_defn *langdef,
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);
}
@@ -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
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
@@ -5331,7 +5370,7 @@ allocate_symbol (struct objfile *objfile)
struct symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
- SYMBOL_SECTION (result) = -1;
+ initialize_objfile_symbol_1 (result);
return result;
}
@@ -5345,7 +5384,7 @@ allocate_template_symbol (struct objfile *objfile)
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;
}
@@ -5355,7 +5394,8 @@ allocate_template_symbol (struct objfile *objfile)
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. */
@@ -5363,7 +5403,9 @@ symbol_objfile (const struct symbol *symbol)
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. */
@@ -5371,7 +5413,8 @@ symbol_arch (const struct symbol *symbol)
struct symtab *
symbol_symtab (const struct symbol *symbol)
{
- return symbol->symtab;
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ return symbol->owner.symtab;
}
/* See symtab.h. */
@@ -5379,7 +5422,8 @@ symbol_symtab (const struct symbol *symbol)
void
symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
{
- symbol->symtab = symtab;
+ gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ symbol->owner.symtab = symtab;
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index b3a9a6b..3f645b1 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -711,10 +711,19 @@ struct symbol
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. */
@@ -726,6 +735,11 @@ struct symbol
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;
@@ -742,6 +756,7 @@ struct symbol
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
@@ -769,10 +784,14 @@ struct symbol
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) \