]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/symtab.c
Rename make_symbol_completion_list_fn -> symbol_completer
[thirdparty/binutils-gdb.git] / gdb / symtab.c
index cc2f4001e0db43309edbde25dbb138f3fe2a7ee5..e5cd397f6ca434ee842c75b644c1a0a4fda250d4 100644 (file)
@@ -61,6 +61,9 @@
 
 #include "parser-defs.h"
 #include "completer.h"
+#include "progspace-and-thread.h"
+#include "common/gdb_optional.h"
+#include "filename-seen-cache.h"
 
 /* Forward declarations for local functions.  */
 
@@ -2623,7 +2626,8 @@ symbol_matches_domain (enum language symbol_language,
      Similarly, any Ada type declaration implicitly defines a typedef.  */
   if (symbol_language == language_cplus
       || symbol_language == language_d
-      || symbol_language == language_ada)
+      || symbol_language == language_ada
+      || symbol_language == language_rust)
     {
       if ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN)
          && symbol_domain == STRUCT_DOMAIN)
@@ -3289,15 +3293,15 @@ done:
 }
 
 /* Given SYMTAB, returns all the PCs function in the symtab that
-   exactly match LINE.  Returns NULL if there are no exact matches,
-   but updates BEST_ITEM in this case.  */
+   exactly match LINE.  Returns an empty vector if there are no exact
+   matches, but updates BEST_ITEM in this case.  */
 
-VEC (CORE_ADDR) *
+std::vector<CORE_ADDR>
 find_pcs_for_symtab_line (struct symtab *symtab, int line,
                          struct linetable_entry **best_item)
 {
   int start = 0;
-  VEC (CORE_ADDR) *result = NULL;
+  std::vector<CORE_ADDR> result;
 
   /* First, collect all the PCs that are at this line.  */
   while (1)
@@ -3320,8 +3324,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
          break;
        }
 
-      VEC_safe_push (CORE_ADDR, result,
-                    SYMTAB_LINETABLE (symtab)->item[idx].pc);
+      result.push_back (SYMTAB_LINETABLE (symtab)->item[idx].pc);
       start = idx + 1;
     }
 
@@ -3552,7 +3555,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
 {
   struct symbol *sym;
   struct symtab_and_line start_sal;
-  struct cleanup *old_chain;
   CORE_ADDR pc, saved_pc;
   struct obj_section *section;
   const char *name;
@@ -3565,7 +3567,8 @@ skip_prologue_sal (struct symtab_and_line *sal)
   if (sal->explicit_pc)
     return;
 
-  old_chain = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
+
   switch_to_program_space_and_thread (sal->pspace);
 
   sym = find_pc_sect_function (sal->pc, sal->section);
@@ -3584,10 +3587,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
         = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
 
       if (msymbol.minsym == NULL)
-       {
-         do_cleanups (old_chain);
-         return;
-       }
+       return;
 
       objfile = msymbol.objfile;
       pc = BMSYMBOL_VALUE_ADDRESS (msymbol);
@@ -3679,8 +3679,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
       start_sal = find_pc_sect_line (pc, section, 0);
     }
 
-  do_cleanups (old_chain);
-
   /* If we're already past the prologue, leave SAL unchanged.  Otherwise
      forward SAL to the end of the prologue.  */
   if (sal->pc >= pc)
@@ -3971,74 +3969,6 @@ operator_chars (const char *p, const char **end)
 }
 \f
 
-/* Cache to watch for file names already seen by filename_seen.  */
-
-struct filename_seen_cache
-{
-  /* Table of files seen so far.  */
-  htab_t tab;
-  /* Initial size of the table.  It automagically grows from here.  */
-#define INITIAL_FILENAME_SEEN_CACHE_SIZE 100
-};
-
-/* filename_seen_cache constructor.  */
-
-static struct filename_seen_cache *
-create_filename_seen_cache (void)
-{
-  struct filename_seen_cache *cache = XNEW (struct filename_seen_cache);
-
-  cache->tab = htab_create_alloc (INITIAL_FILENAME_SEEN_CACHE_SIZE,
-                                 filename_hash, filename_eq,
-                                 NULL, xcalloc, xfree);
-
-  return cache;
-}
-
-/* Empty the cache, but do not delete it.  */
-
-static void
-clear_filename_seen_cache (struct filename_seen_cache *cache)
-{
-  htab_empty (cache->tab);
-}
-
-/* filename_seen_cache destructor.
-   This takes a void * argument as it is generally used as a cleanup.  */
-
-static void
-delete_filename_seen_cache (void *ptr)
-{
-  struct filename_seen_cache *cache = (struct filename_seen_cache *) ptr;
-
-  htab_delete (cache->tab);
-  xfree (cache);
-}
-
-/* If FILE is not already in the table of files in CACHE, return zero;
-   otherwise return non-zero.  Optionally add FILE to the table if ADD
-   is non-zero.
-
-   NOTE: We don't manage space for FILE, we assume FILE lives as long
-   as the caller needs.  */
-
-static int
-filename_seen (struct filename_seen_cache *cache, const char *file, int add)
-{
-  void **slot;
-
-  /* Is FILE in tab?  */
-  slot = htab_find_slot (cache->tab, file, add ? INSERT : NO_INSERT);
-  if (*slot != NULL)
-    return 1;
-
-  /* No; maybe add it to tab.  */
-  if (add)
-    *slot = (char *) file;
-
-  return 0;
-}
-
 /* Data structure to maintain printing state for output_source_filename.  */
 
 struct output_source_filename_data
@@ -4068,7 +3998,7 @@ output_source_filename (const char *name,
      symtabs; it doesn't hurt to check.  */
 
   /* Was NAME already seen?  */
-  if (filename_seen (data->filename_seen_cache, name, 1))
+  if (data->filename_seen_cache->seen (name))
     {
       /* Yes; don't print it again.  */
       return;
@@ -4100,16 +4030,15 @@ sources_info (char *ignore, int from_tty)
   struct symtab *s;
   struct objfile *objfile;
   struct output_source_filename_data data;
-  struct cleanup *cleanups;
 
   if (!have_full_symbols () && !have_partial_symbols ())
     {
       error (_("No symbol table is loaded.  Use the \"file\" command."));
     }
 
-  data.filename_seen_cache = create_filename_seen_cache ();
-  cleanups = make_cleanup (delete_filename_seen_cache,
-                          data.filename_seen_cache);
+  filename_seen_cache filenames_seen;
+
+  data.filename_seen_cache = &filenames_seen;
 
   printf_filtered ("Source files for which symbols have been read in:\n\n");
 
@@ -4125,13 +4054,11 @@ sources_info (char *ignore, int from_tty)
   printf_filtered ("Source files for which symbols "
                   "will be read in on demand:\n\n");
 
-  clear_filename_seen_cache (data.filename_seen_cache);
+  filenames_seen.clear ();
   data.first = 1;
   map_symbol_filenames (output_partial_symbol_filename, &data,
                        1 /*need_fullname*/);
   printf_filtered ("\n");
-
-  do_cleanups (cleanups);
 }
 
 /* Compare FILE against all the NFILES entries of FILES.  If BASENAMES is
@@ -4304,9 +4231,7 @@ search_symbols (const char *regexp, enum search_domain kind,
   struct symbol_search *found;
   struct symbol_search *tail;
   int nfound;
-  /* This is true if PREG contains valid data, false otherwise.  */
-  bool preg_p;
-  regex_t preg;
+  gdb::optional<compiled_regex> preg;
 
   /* OLD_CHAIN .. RETVAL_CHAIN is always freed, RETVAL_CHAIN .. current
      CLEANUP_CHAIN is freed only in the case of an error.  */
@@ -4321,7 +4246,6 @@ search_symbols (const char *regexp, enum search_domain kind,
   ourtype4 = types4[kind];
 
   *matches = NULL;
-  preg_p = false;
 
   if (regexp != NULL)
     {
@@ -4360,18 +4284,9 @@ search_symbols (const char *regexp, enum search_domain kind,
            }
        }
 
-      errcode = regcomp (&preg, regexp,
-                        REG_NOSUB | (case_sensitivity == case_sensitive_off
-                                     ? REG_ICASE : 0));
-      if (errcode != 0)
-       {
-         char *err = get_regcomp_error (errcode, &preg);
-
-         make_cleanup (xfree, err);
-         error (_("Invalid regexp (%s): %s"), err, regexp);
-       }
-      preg_p = true;
-      make_regfree_cleanup (&preg);
+      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
+                               ? REG_ICASE : 0);
+      preg.emplace (regexp, cflags, _("Invalid regexp"));
     }
 
   /* Search through the partial symtabs *first* for all symbols
@@ -4384,8 +4299,8 @@ search_symbols (const char *regexp, enum search_domain kind,
                           },
                           [&] (const char *symname)
                           {
-                            return (!preg_p || regexec (&preg, symname,
-                                                        0, NULL, 0) == 0);
+                            return (!preg || preg->exec (symname,
+                                                         0, NULL, 0) == 0);
                           },
                           NULL,
                           kind);
@@ -4420,9 +4335,9 @@ search_symbols (const char *regexp, enum search_domain kind,
            || MSYMBOL_TYPE (msymbol) == ourtype3
            || MSYMBOL_TYPE (msymbol) == ourtype4)
          {
-           if (!preg_p
-               || regexec (&preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
-                           NULL, 0) == 0)
+           if (!preg
+               || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
+                              NULL, 0) == 0)
              {
                /* Note: An important side-effect of these lookup functions
                   is to expand the symbol table if msymbol is found, for the
@@ -4464,9 +4379,9 @@ search_symbols (const char *regexp, enum search_domain kind,
                                       files, nfiles, 1))
                     && file_matches (symtab_to_fullname (real_symtab),
                                      files, nfiles, 0)))
-               && ((!preg_p
-                    || regexec (&preg, SYMBOL_NATURAL_NAME (sym), 0,
-                                NULL, 0) == 0)
+               && ((!preg
+                    || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
+                                   NULL, 0) == 0)
                    && ((kind == VARIABLES_DOMAIN
                         && SYMBOL_CLASS (sym) != LOC_TYPEDEF
                         && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
@@ -4522,9 +4437,8 @@ search_symbols (const char *regexp, enum search_domain kind,
            || MSYMBOL_TYPE (msymbol) == ourtype3
            || MSYMBOL_TYPE (msymbol) == ourtype4)
          {
-           if (!preg_p
-               || regexec (&preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
-                           NULL, 0) == 0)
+           if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
+                                    NULL, 0) == 0)
              {
                /* For functions we can do a quick check of whether the
                   symbol might be found via find_pc_symtab.  */
@@ -4854,18 +4768,8 @@ do_free_completion_list (void *list)
   free_completion_list ((VEC (char_ptr) **) list);
 }
 
-/* Helper routine for make_symbol_completion_list.  */
-
 static VEC (char_ptr) *return_val;
 
-#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
-      completion_list_add_name \
-       (SYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
-
-#define MCOMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
-      completion_list_add_name \
-       (MSYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
-
 /* Tracker for how many unique completions have been generated.  Used
    to terminate completion list generation early if the list has grown
    to a size so large as to be useless.  This helps avoid GDB seeming
@@ -4935,6 +4839,28 @@ completion_list_add_name (const char *symname,
   }
 }
 
+/* completion_list_add_name wrapper for struct symbol.  */
+
+static void
+completion_list_add_symbol (symbol *sym,
+                           const char *sym_text, int sym_text_len,
+                           const char *text, const char *word)
+{
+  completion_list_add_name (SYMBOL_NATURAL_NAME (sym),
+                           sym_text, sym_text_len, text, word);
+}
+
+/* completion_list_add_name wrapper for struct minimal_symbol.  */
+
+static void
+completion_list_add_msymbol (minimal_symbol *sym,
+                            const char *sym_text, int sym_text_len,
+                            const char *text, const char *word)
+{
+  completion_list_add_name (MSYMBOL_NATURAL_NAME (sym),
+                           sym_text, sym_text_len, text, word);
+}
+
 /* ObjC: In case we are completing on a selector, look as the msymbol
    again and feed all the selectors into the mill.  */
 
@@ -5085,7 +5011,7 @@ add_symtab_completions (struct compunit_symtab *cust,
          if (code == TYPE_CODE_UNDEF
              || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
                  && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
-           COMPLETION_LIST_ADD_SYMBOL (sym,
+           completion_list_add_symbol (sym,
                                        sym_text, sym_text_len,
                                        text, word);
        }
@@ -5196,7 +5122,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
       ALL_MSYMBOLS (objfile, msymbol)
        {
          QUIT;
-         MCOMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text,
+         completion_list_add_msymbol (msymbol, sym_text, sym_text_len, text,
                                       word);
 
          completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text,
@@ -5243,14 +5169,14 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
          {
            if (code == TYPE_CODE_UNDEF)
              {
-               COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
+               completion_list_add_symbol (sym, sym_text, sym_text_len, text,
                                            word);
                completion_list_add_fields (sym, sym_text, sym_text_len, text,
                                            word);
              }
            else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
                     && TYPE_CODE (SYMBOL_TYPE (sym)) == code)
-             COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
+             completion_list_add_symbol (sym, sym_text, sym_text_len, text,
                                          word);
          }
 
@@ -5373,24 +5299,13 @@ make_symbol_completion_type (const char *text, const char *word,
   return current_language->la_make_symbol_completion_list (text, word, code);
 }
 
-/* Like make_symbol_completion_list, but suitable for use as a
-   completion function.  */
-
-VEC (char_ptr) *
-make_symbol_completion_list_fn (struct cmd_list_element *ignore,
-                               const char *text, const char *word)
-{
-  return make_symbol_completion_list (text, word);
-}
-
 /* Like make_symbol_completion_list, but returns a list of symbols
-   defined in a source file FILE.  */
+   defined in all source files name SRCFILE.  */
 
 static VEC (char_ptr) *
 make_file_symbol_completion_list_1 (const char *text, const char *word,
                                    const char *srcfile)
 {
-  struct symtab *s;
   /* The symbol we are completing on.  Points in same buffer as text.  */
   const char *sym_text;
   /* Length of sym_text.  */
@@ -5441,28 +5356,15 @@ make_file_symbol_completion_list_1 (const char *text, const char *word,
 
   sym_text_len = strlen (sym_text);
 
-  /* Find the symtab for SRCFILE (this loads it if it was not yet read
-     in).  */
-  s = lookup_symtab (srcfile);
-  if (s == NULL)
+  /* Go through symtabs for SRCFILE and check the externs and statics
+     for symbols which match.  */
+  iterate_over_symtabs (srcfile, [&] (symtab *s)
     {
-      /* Maybe they typed the file with leading directories, while the
-        symbol tables record only its basename.  */
-      const char *tail = lbasename (srcfile);
-
-      if (tail > srcfile)
-       s = lookup_symtab (tail);
-    }
-
-  /* If we have no symtab for that file, return an empty list.  */
-  if (s == NULL)
-    return (return_val);
-
-  /* Go through this symtab and check the externs and statics for
-     symbols which match.  */
-  add_symtab_completions (SYMTAB_COMPUNIT (s),
-                         sym_text, sym_text_len,
-                         text, word, TYPE_CODE_UNDEF);
+      add_symtab_completions (SYMTAB_COMPUNIT (s),
+                             sym_text, sym_text_len,
+                             text, word, TYPE_CODE_UNDEF);
+      return false;
+    });
 
   return (return_val);
 }
@@ -5570,7 +5472,7 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
 
   if (not_interesting_fname (filename))
     return;
-  if (!filename_seen (data->filename_seen_cache, filename, 1)
+  if (!data->filename_seen_cache->seen (filename)
       && filename_ncmp (filename, data->text, data->text_len) == 0)
     {
       /* This file matches for a completion; add it to the
@@ -5582,7 +5484,7 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
       const char *base_name = lbasename (filename);
 
       if (base_name != filename
-         && !filename_seen (data->filename_seen_cache, base_name, 1)
+         && !data->filename_seen_cache->seen (base_name)
          && filename_ncmp (base_name, data->text, data->text_len) == 0)
        add_filename_to_list (base_name, data->text, data->word, data->list);
     }
@@ -5603,23 +5505,20 @@ make_source_files_completion_list (const char *text, const char *word)
   VEC (char_ptr) *list = NULL;
   const char *base_name;
   struct add_partial_filename_data datum;
-  struct filename_seen_cache *filename_seen_cache;
-  struct cleanup *back_to, *cache_cleanup;
+  struct cleanup *back_to;
 
   if (!have_full_symbols () && !have_partial_symbols ())
     return list;
 
   back_to = make_cleanup (do_free_completion_list, &list);
 
-  filename_seen_cache = create_filename_seen_cache ();
-  cache_cleanup = make_cleanup (delete_filename_seen_cache,
-                               filename_seen_cache);
+  filename_seen_cache filenames_seen;
 
   ALL_FILETABS (objfile, cu, s)
     {
       if (not_interesting_fname (s->filename))
        continue;
-      if (!filename_seen (filename_seen_cache, s->filename, 1)
+      if (!filenames_seen.seen (s->filename)
          && filename_ncmp (s->filename, text, text_len) == 0)
        {
          /* This file matches for a completion; add it to the current
@@ -5634,13 +5533,13 @@ make_source_files_completion_list (const char *text, const char *word)
             command do when they parse file names.  */
          base_name = lbasename (s->filename);
          if (base_name != s->filename
-             && !filename_seen (filename_seen_cache, base_name, 1)
+             && !filenames_seen.seen (base_name)
              && filename_ncmp (base_name, text, text_len) == 0)
            add_filename_to_list (base_name, text, word, &list);
        }
     }
 
-  datum.filename_seen_cache = filename_seen_cache;
+  datum.filename_seen_cache = &filenames_seen;
   datum.text = text;
   datum.word = word;
   datum.text_len = text_len;
@@ -5648,7 +5547,6 @@ make_source_files_completion_list (const char *text, const char *word)
   map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
                        0 /*need_fullname*/);
 
-  do_cleanups (cache_cleanup);
   discard_cleanups (back_to);
 
   return list;