Look up primitive types as symbols.
authorDoug Evans <xdje42@gmail.com>
Tue, 23 Dec 2014 15:55:39 +0000 (07:55 -0800)
committerDoug Evans <xdje42@gmail.com>
Tue, 23 Dec 2014 15:58:14 +0000 (07:58 -0800)
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.

15 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/block.c
gdb/block.h
gdb/c-exp.y
gdb/cp-namespace.c
gdb/gdbtypes.c
gdb/guile/scm-symbol.c
gdb/language.c
gdb/language.h
gdb/printcmd.c
gdb/python/py-symbol.c
gdb/symmisc.c
gdb/symtab.c
gdb/symtab.h

index acf692fdcaf3ee6b537facbb88f9dd32b40d54e8..dc1cb15f1a373bfae7775d68d5b86f51f83e8049 100644 (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>
 
        * symtab.h (SYMBOL_DOMAIN_BITS): New macro.
index 5d4ea2f5c08d491fecbae25b241744ce92836f44..5d5d61319035cc6873217b0b51749b9dad64f26d 100644 (file)
@@ -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
index e791c73accff1ce69a7b33917a1bdc7e693748ce..8d45b6ed97c178bea5120ca29e1ecd93b0bbb347 100644 (file)
@@ -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.  */
index 409a5c750c261cd301d0748a2af147eb1cdbb562..e6c5feb499884c8ba4636c67f9ea48710999d4ed 100644 (file)
@@ -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 *);
index 707e504ebe224d7564d7ecb94cdcd33aed7c5668..91728eeac296cba614d37e7cc2192146800d69b3 100644 (file)
@@ -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)
     {
index 6599d45eb0097afe37d192c0e2b4993c049d9288..9e9dce009d63a8e500984a30ef6a983e7e86b395 100644 (file)
@@ -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)
index 0048f6a1a5f91695027d69ba5df5546ffa47ee4e..0297243621fa869863cd42d7c1a1bb95b4bb85a5 100644 (file)
@@ -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);
index 6a1964856734f456b2722ed5b5c28f58315c66ea..a627f94d522d73b434ed910dfc49360730a566d7 100644 (file)
@@ -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;
+};
 \f
 /* 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);
 }
index df45ddd97c06a294e6c164945070fcb9c446faa6..fa43857ab83873e65e3dc9f09c685033adf40204 100644 (file)
@@ -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.  */
index 2a47e645344bdc9a429e75e4ab833d446b7c90da..1103fe92dcb2cc11b1ee0640a566d7f00cf7c755 100644 (file)
@@ -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);
+
 \f
 /* These macros define the behaviour of the expression 
    evaluator.  */
index 58b7ac0b4d5035ba75da3583248fcfc053a5a420..020a47c6d8b5d87fa01ee5d53ac2a6fcc75aa5e7 100644 (file)
@@ -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)
index 62fde6482f73080af8f9ce88f9b7876658dac252..fdff53fa15a797a0f90d0053715392aaf8ed4f04 100644 (file)
@@ -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),
index 3b6639df6515f0c42d0f9594ec0650af54e1262d..9ae0847f58bbdcae0e9466af4589d47a888ef1da 100644 (file)
@@ -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)
index e7cd5afc8c7b9145ed0fd3725e5851c3f6f37f43..0efd9d2d4841ab70224fd5315e663777adbdb939 100644 (file)
@@ -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)
 
 \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
@@ -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;
 }
 
 \f
index b3a9a6b74eb60f834ecad42f9531ccd3973a15c3..3f645b1bd9c625432f067b51e24b183950a7b946 100644 (file)
@@ -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) \