*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / psymtab.c
index 9620de8bd351f6e15fc874c0a987e6816f194f75..5623e2dc5f8ba30d6b1aa52cb6c9fa3579855d70 100644 (file)
@@ -135,6 +135,10 @@ partial_map_expand_apply (struct objfile *objfile,
 {
   struct symtab *last_made = objfile->symtabs;
 
+  /* Shared psymtabs should never be seen here.  Instead they should
+     be handled properly by the caller.  */
+  gdb_assert (pst->user == NULL);
+
   /* Don't visit already-expanded psymtabs.  */
   if (pst->readin)
     return 0;
@@ -165,6 +169,15 @@ partial_map_symtabs_matching_filename (struct objfile *objfile,
 
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
   {
+    /* We can skip shared psymtabs here, because any file name will be
+       attached to the unshared psymtab.  */
+    if (pst->user != NULL)
+      continue;
+
+    /* Anonymous psymtabs don't have a file name.  */
+    if (pst->anonymous)
+      continue;
+
     if (FILENAME_CMP (name, pst->filename) == 0
        || (!is_abs && compare_filenames_for_search (pst->filename,
                                                     name, name_len)))
@@ -388,7 +401,8 @@ find_pc_sect_symtab_from_partial (struct objfile *objfile,
        warning (_("\
 (Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
                 paddress (get_objfile_arch (ps->objfile), pc));
-      return psymtab_to_symtab (ps);
+      psymtab_to_symtab (ps);
+      return ps->symtab;
     }
   return NULL;
 }
@@ -500,6 +514,7 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
 {
   struct partial_symtab *ps;
   const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
+  struct symtab *stab_best = NULL;
 
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
   {
@@ -520,13 +535,18 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
          }
 
        if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
-         return stab;
+         {
+           if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+             return stab;
+
+           stab_best = stab;
+         }
 
        /* Keep looking through other psymtabs.  */
       }
   }
 
-  return NULL;
+  return stab_best;
 }
 
 /* Look in PST for a symbol in DOMAIN whose name matches NAME.  Search
@@ -760,6 +780,11 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
 static struct symtab *
 psymtab_to_symtab (struct partial_symtab *pst)
 {
+  /* If it is a shared psymtab, find an unshared psymtab that includes
+     it.  Any such psymtab will do.  */
+  while (pst->user != NULL)
+    pst = pst->user;
+
   /* If it's been looked up before, return it.  */
   if (pst->symtab)
     return pst->symtab;
@@ -952,8 +977,16 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   int i;
 
-  fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
-                   psymtab->filename);
+  if (psymtab->anonymous)
+    {
+      fprintf_filtered (outfile, "\nAnonymous partial symtab (%s) ",
+                       psymtab->filename);
+    }
+  else
+    {
+      fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
+                       psymtab->filename);
+    }
   fprintf_filtered (outfile, "(object ");
   gdb_print_host_address (psymtab, outfile);
   fprintf_filtered (outfile, ")\n\n");
@@ -1000,6 +1033,12 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
       fprintf_filtered (outfile, " %s\n",
                        psymtab->dependencies[i]->filename);
     }
+  if (psymtab->user != NULL)
+    {
+      fprintf_filtered (outfile, "  Shared partial symtab with user ");
+      gdb_print_host_address (psymtab->user, outfile);
+      fprintf_filtered (outfile, "\n");
+    }
   if (psymtab->n_global_syms > 0)
     {
       print_partial_symbols (gdbarch,
@@ -1097,6 +1136,10 @@ read_psymtabs_with_filename (struct objfile *objfile, const char *filename)
 
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
     {
+      /* Anonymous psymtabs don't have a name of a source file.  */
+      if (p->anonymous)
+       continue;
+
       if (filename_cmp (filename, p->filename) == 0)
        psymtab_to_symtab (p);
     }
@@ -1116,6 +1159,15 @@ map_symbol_filenames_psymtab (struct objfile *objfile,
       if (ps->readin)
        continue;
 
+      /* We can skip shared psymtabs here, because any file name will be
+        attached to the unshared psymtab.  */
+      if (ps->user != NULL)
+       continue;
+
+      /* Anonymous psymtabs don't have a file name.  */
+      if (ps->anonymous)
+       continue;
+
       QUIT;
       if (need_fullname)
        fullname = psymtab_to_fullname (ps);
@@ -1140,6 +1192,8 @@ psymtab_to_fullname (struct partial_symtab *ps)
 
   if (!ps)
     return NULL;
+  if (ps->anonymous)
+    return NULL;
 
   /* Use cached copy if we have it.
      We rely on forget_cached_source_info being called appropriately
@@ -1236,6 +1290,94 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace,
     }
 }          
 
+/* A helper for expand_symtabs_matching_via_partial that handles
+   searching included psymtabs.  This returns 1 if a symbol is found,
+   and zero otherwise.  It also updates the 'searched_flag' on the
+   various psymtabs that it searches.  */
+
+static int
+recursively_search_psymtabs (struct partial_symtab *ps,
+                            struct objfile *objfile,
+                            enum search_domain kind,
+                            int (*name_matcher) (const char *, void *),
+                            void *data)
+{
+  struct partial_symbol **psym;
+  struct partial_symbol **bound, **gbound, **sbound;
+  int keep_going = 1;
+  int result = PST_SEARCHED_AND_NOT_FOUND;
+  int i;
+
+  if (ps->searched_flag != PST_NOT_SEARCHED)
+    return ps->searched_flag == PST_SEARCHED_AND_FOUND;
+
+  /* Recurse into shared psymtabs first, because they may have already
+     been searched, and this could save some time.  */
+  for (i = 0; i < ps->number_of_dependencies; ++i)
+    {
+      int r;
+
+      /* Skip non-shared dependencies, these are handled elsewhere.  */
+      if (ps->dependencies[i]->user == NULL)
+       continue;
+
+      r = recursively_search_psymtabs (ps->dependencies[i],
+                                      objfile, kind, name_matcher, data);
+      if (r != 0)
+       {
+         ps->searched_flag = PST_SEARCHED_AND_FOUND;
+         return 1;
+       }
+    }
+
+  gbound = (objfile->global_psymbols.list
+           + ps->globals_offset + ps->n_global_syms);
+  sbound = (objfile->static_psymbols.list
+           + ps->statics_offset + ps->n_static_syms);
+  bound = gbound;
+
+  /* Go through all of the symbols stored in a partial
+     symtab in one loop.  */
+  psym = objfile->global_psymbols.list + ps->globals_offset;
+  while (keep_going)
+    {
+      if (psym >= bound)
+       {
+         if (bound == gbound && ps->n_static_syms != 0)
+           {
+             psym = objfile->static_psymbols.list + ps->statics_offset;
+             bound = sbound;
+           }
+         else
+           keep_going = 0;
+         continue;
+       }
+      else
+       {
+         QUIT;
+
+         if ((kind == ALL_DOMAIN
+              || (kind == VARIABLES_DOMAIN
+                  && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+                  && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+              || (kind == FUNCTIONS_DOMAIN
+                  && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+              || (kind == TYPES_DOMAIN
+                  && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
+             && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
+           {
+             /* Found a match, so notify our caller.  */
+             result = PST_SEARCHED_AND_FOUND;
+             keep_going = 0;
+           }
+       }
+      psym++;
+    }
+
+  ps->searched_flag = result;
+  return result == PST_SEARCHED_AND_FOUND;
+}
+
 static void
 expand_symtabs_matching_via_partial
   (struct objfile *objfile,
@@ -1246,60 +1388,32 @@ expand_symtabs_matching_via_partial
 {
   struct partial_symtab *ps;
 
+  /* Clear the search flags.  */
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
     {
-      struct partial_symbol **psym;
-      struct partial_symbol **bound, **gbound, **sbound;
-      int keep_going = 1;
+      ps->searched_flag = PST_NOT_SEARCHED;
+    }
 
+  ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
+    {
       if (ps->readin)
        continue;
 
-      if (file_matcher && ! (*file_matcher) (ps->filename, data))
+      /* We skip shared psymtabs because file-matching doesn't apply
+        to them; but we search them later in the loop.  */
+      if (ps->user != NULL)
        continue;
 
-      gbound = objfile->global_psymbols.list
-       + ps->globals_offset + ps->n_global_syms;
-      sbound = objfile->static_psymbols.list
-       + ps->statics_offset + ps->n_static_syms;
-      bound = gbound;
-
-      /* Go through all of the symbols stored in a partial
-        symtab in one loop.  */
-      psym = objfile->global_psymbols.list + ps->globals_offset;
-      while (keep_going)
+      if (file_matcher)
        {
-         if (psym >= bound)
-           {
-             if (bound == gbound && ps->n_static_syms != 0)
-               {
-                 psym = objfile->static_psymbols.list + ps->statics_offset;
-                 bound = sbound;
-               }
-             else
-               keep_going = 0;
-             continue;
-           }
-         else
-           {
-             QUIT;
-
-             if ((kind == ALL_DOMAIN
-                  || (kind == VARIABLES_DOMAIN
-                      && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
-                      && SYMBOL_CLASS (*psym) != LOC_BLOCK)
-                  || (kind == FUNCTIONS_DOMAIN
-                      && SYMBOL_CLASS (*psym) == LOC_BLOCK)
-                  || (kind == TYPES_DOMAIN
-                      && SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
-                 && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
-               {
-                 psymtab_to_symtab (ps);
-                 keep_going = 0;
-               }
-           }
-         psym++;
+         if (ps->anonymous)
+           continue;
+         if (! (*file_matcher) (ps->filename, data))
+           continue;
        }
+
+      if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data))
+       psymtab_to_symtab (ps);
     }
 }
 
@@ -1649,6 +1763,26 @@ allocate_psymtab (const char *filename, struct objfile *objfile)
   psymtab->next = objfile->psymtabs;
   objfile->psymtabs = psymtab;
 
+  if (symtab_create_debug)
+    {
+      /* Be a bit clever with debugging messages, and don't print objfile
+        every time, only when it changes.  */
+      static char *last_objfile_name = NULL;
+
+      if (last_objfile_name == NULL
+         || strcmp (last_objfile_name, objfile->name) != 0)
+       {
+         xfree (last_objfile_name);
+         last_objfile_name = xstrdup (objfile->name);
+         fprintf_unfiltered (gdb_stdlog,
+                             "Creating one or more psymtabs for objfile %s ...\n",
+                             last_objfile_name);
+       }
+      fprintf_unfiltered (gdb_stdlog,
+                         "Created psymtab %s for module %s.\n",
+                         host_address_to_string (psymtab), filename);
+    }
+
   return (psymtab);
 }
 
This page took 0.034891 seconds and 4 git commands to generate.