aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c272
1 files changed, 91 insertions, 181 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e5cd397..57fb355 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4747,44 +4747,13 @@ compare_symbol_name (const char *name, const char *sym_text, int sym_text_len)
return 1;
}
-/* Free any memory associated with a completion list. */
-
-static void
-free_completion_list (VEC (char_ptr) **list_ptr)
-{
- int i;
- char *p;
-
- for (i = 0; VEC_iterate (char_ptr, *list_ptr, i, p); ++i)
- xfree (p);
- VEC_free (char_ptr, *list_ptr);
-}
-
-/* Callback for make_cleanup. */
-
-static void
-do_free_completion_list (void *list)
-{
- free_completion_list ((VEC (char_ptr) **) list);
-}
-
-static VEC (char_ptr) *return_val;
-
-/* 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
- to lock up in the event the user requests to complete on something
- vague that necessitates the time consuming expansion of many symbol
- tables. */
-
-static completion_tracker_t completion_tracker;
-
/* Test to see if the symbol specified by SYMNAME (which is already
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
characters. If so, add it to the current completion list. */
static void
-completion_list_add_name (const char *symname,
+completion_list_add_name (completion_tracker &tracker,
+ const char *symname,
const char *sym_text, int sym_text_len,
const char *text, const char *word)
{
@@ -4797,7 +4766,6 @@ completion_list_add_name (const char *symname,
{
char *newobj;
- enum maybe_add_completion_enum add_status;
if (word == sym_text)
{
@@ -4819,45 +4787,33 @@ completion_list_add_name (const char *symname,
strcat (newobj, symname);
}
- add_status = maybe_add_completion (completion_tracker, newobj);
+ gdb::unique_xmalloc_ptr<char> completion (newobj);
- switch (add_status)
- {
- case MAYBE_ADD_COMPLETION_OK:
- VEC_safe_push (char_ptr, return_val, newobj);
- break;
- case MAYBE_ADD_COMPLETION_OK_MAX_REACHED:
- VEC_safe_push (char_ptr, return_val, newobj);
- throw_max_completions_reached_error ();
- case MAYBE_ADD_COMPLETION_MAX_REACHED:
- xfree (newobj);
- throw_max_completions_reached_error ();
- case MAYBE_ADD_COMPLETION_DUPLICATE:
- xfree (newobj);
- break;
- }
+ tracker.add_completion (std::move (completion));
}
}
/* completion_list_add_name wrapper for struct symbol. */
static void
-completion_list_add_symbol (symbol *sym,
+completion_list_add_symbol (completion_tracker &tracker,
+ symbol *sym,
const char *sym_text, int sym_text_len,
const char *text, const char *word)
{
- completion_list_add_name (SYMBOL_NATURAL_NAME (sym),
+ completion_list_add_name (tracker, 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,
+completion_list_add_msymbol (completion_tracker &tracker,
+ 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),
+ completion_list_add_name (tracker, MSYMBOL_NATURAL_NAME (sym),
sym_text, sym_text_len, text, word);
}
@@ -4865,7 +4821,8 @@ completion_list_add_msymbol (minimal_symbol *sym,
again and feed all the selectors into the mill. */
static void
-completion_list_objc_symbol (struct minimal_symbol *msymbol,
+completion_list_objc_symbol (completion_tracker &tracker,
+ struct minimal_symbol *msymbol,
const char *sym_text, int sym_text_len,
const char *text, const char *word)
{
@@ -4883,7 +4840,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol,
if (sym_text[0] == '[')
/* Complete on shortened method method. */
- completion_list_add_name (method + 1, sym_text, sym_text_len, text, word);
+ completion_list_add_name (tracker, method + 1,
+ sym_text, sym_text_len, text, word);
while ((strlen (method) + 1) >= tmplen)
{
@@ -4904,9 +4862,11 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol,
memcpy (tmp, method, (category - method));
tmp[category - method] = ' ';
memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
- completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ completion_list_add_name (tracker, tmp,
+ sym_text, sym_text_len, text, word);
if (sym_text[0] == '[')
- completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word);
+ completion_list_add_name (tracker, tmp + 1,
+ sym_text, sym_text_len, text, word);
}
if (selector != NULL)
@@ -4917,7 +4877,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol,
if (tmp2 != NULL)
*tmp2 = '\0';
- completion_list_add_name (tmp, sym_text, sym_text_len, text, word);
+ completion_list_add_name (tracker, tmp,
+ sym_text, sym_text_len, text, word);
}
}
@@ -4968,9 +4929,10 @@ language_search_unquoted_string (const char *text, const char *p)
}
static void
-completion_list_add_fields (struct symbol *sym, const char *sym_text,
- int sym_text_len, const char *text,
- const char *word)
+completion_list_add_fields (completion_tracker &tracker,
+ struct symbol *sym,
+ const char *sym_text, int sym_text_len,
+ const char *text, const char *word)
{
if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
@@ -4981,7 +4943,7 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text,
if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
if (TYPE_FIELD_NAME (t, j))
- completion_list_add_name (TYPE_FIELD_NAME (t, j),
+ completion_list_add_name (tracker, TYPE_FIELD_NAME (t, j),
sym_text, sym_text_len, text, word);
}
}
@@ -4990,6 +4952,7 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text,
static void
add_symtab_completions (struct compunit_symtab *cust,
+ completion_tracker &tracker,
const char *sym_text, int sym_text_len,
const char *text, const char *word,
enum type_code code)
@@ -5011,18 +4974,18 @@ 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 (tracker, sym,
sym_text, sym_text_len,
text, word);
}
}
}
-static void
-default_make_symbol_completion_list_break_on_1 (const char *text,
- const char *word,
- const char *break_on,
- enum type_code code)
+void
+default_collect_symbol_completion_matches_break_on
+ (completion_tracker &tracker,
+ const char *text, const char *word,
+ const char *break_on, enum type_code code)
{
/* Problem: All of the symbols have to be copied because readline
frees them. I'm not going to worry about this; hopefully there
@@ -5039,7 +5002,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
const char *sym_text;
/* Length of sym_text. */
int sym_text_len;
- struct cleanup *cleanups;
/* Now look for the symbol we are supposed to complete on. */
{
@@ -5109,9 +5071,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
}
gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '(');
- completion_tracker = new_completion_tracker ();
- cleanups = make_cleanup_free_completion_tracker (&completion_tracker);
-
/* At this point scan through the misc symbol vectors and add each
symbol you find to the list. Eventually we want to ignore
anything that isn't a text symbol (everything else will be
@@ -5122,18 +5081,21 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- completion_list_add_msymbol (msymbol, sym_text, sym_text_len, text,
- word);
- completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text,
- word);
+ completion_list_add_msymbol (tracker,
+ msymbol, sym_text, sym_text_len,
+ text, word);
+
+ completion_list_objc_symbol (tracker,
+ msymbol, sym_text, sym_text_len,
+ text, word);
}
}
/* Add completions for all currently loaded symbol tables. */
ALL_COMPUNITS (objfile, cust)
- add_symtab_completions (cust, sym_text, sym_text_len, text, word,
- code);
+ add_symtab_completions (cust, tracker,
+ sym_text, sym_text_len, text, word, code);
/* Look through the partial symtabs for all symbols which begin by
matching SYM_TEXT. Expand all CUs that you find to the list. */
@@ -5147,6 +5109,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
[&] (compunit_symtab *symtab) /* expansion notify */
{
add_symtab_completions (symtab,
+ tracker,
sym_text, sym_text_len,
text, word, code);
},
@@ -5169,14 +5132,17 @@ 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 (tracker, sym,
+ sym_text, sym_text_len, text,
word);
- completion_list_add_fields (sym, sym_text, sym_text_len, text,
+ completion_list_add_fields (tracker, 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 (tracker, sym,
+ sym_text, sym_text_len, text,
word);
}
@@ -5194,11 +5160,13 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
{
if (surrounding_static_block != NULL)
ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
- completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+ completion_list_add_fields (tracker, sym,
+ sym_text, sym_text_len, text, word);
if (surrounding_global_block != NULL)
ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
- completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+ completion_list_add_fields (tracker, sym,
+ sym_text, sym_text_len, text, word);
}
/* Skip macros if we are completing a struct tag -- arguable but
@@ -5214,7 +5182,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
macro_source_file *,
int)
{
- completion_list_add_name (macro_name,
+ completion_list_add_name (tracker, macro_name,
sym_text, sym_text_len,
text, word);
};
@@ -5237,74 +5205,52 @@ default_make_symbol_completion_list_break_on_1 (const char *text,
/* User-defined macros are always visible. */
macro_for_each (macro_user_macros, add_macro_name);
}
-
- do_cleanups (cleanups);
}
-VEC (char_ptr) *
-default_make_symbol_completion_list_break_on (const char *text,
- const char *word,
- const char *break_on,
- enum type_code code)
-{
- struct cleanup *back_to;
-
- return_val = NULL;
- back_to = make_cleanup (do_free_completion_list, &return_val);
-
- TRY
- {
- default_make_symbol_completion_list_break_on_1 (text, word,
- break_on, code);
- }
- CATCH (except, RETURN_MASK_ERROR)
- {
- if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
- throw_exception (except);
- }
- END_CATCH
-
- discard_cleanups (back_to);
- return return_val;
-}
-
-VEC (char_ptr) *
-default_make_symbol_completion_list (const char *text, const char *word,
- enum type_code code)
+void
+default_collect_symbol_completion_matches (completion_tracker &tracker,
+ const char *text, const char *word,
+ enum type_code code)
{
- return default_make_symbol_completion_list_break_on (text, word, "", code);
+ return default_collect_symbol_completion_matches_break_on (tracker,
+ text, word, "",
+ code);
}
-/* Return a vector of all symbols (regardless of class) which begin by
- matching TEXT. If the answer is no symbols, then the return value
- is NULL. */
+/* Collect all symbols (regardless of class) which begin by matching
+ TEXT. */
-VEC (char_ptr) *
-make_symbol_completion_list (const char *text, const char *word)
+void
+collect_symbol_completion_matches (completion_tracker &tracker,
+ const char *text, const char *word)
{
- return current_language->la_make_symbol_completion_list (text, word,
- TYPE_CODE_UNDEF);
+ current_language->la_collect_symbol_completion_matches (tracker,
+ text, word,
+ TYPE_CODE_UNDEF);
}
-/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN
- symbols whose type code is CODE. */
+/* Like collect_symbol_completion_matches, but only collect
+ STRUCT_DOMAIN symbols whose type code is CODE. */
-VEC (char_ptr) *
-make_symbol_completion_type (const char *text, const char *word,
- enum type_code code)
+void
+collect_symbol_completion_matches_type (completion_tracker &tracker,
+ const char *text, const char *word,
+ enum type_code code)
{
gdb_assert (code == TYPE_CODE_UNION
|| code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_ENUM);
- return current_language->la_make_symbol_completion_list (text, word, code);
+ current_language->la_collect_symbol_completion_matches (tracker,
+ text, word, code);
}
-/* Like make_symbol_completion_list, but returns a list of symbols
- defined in all source files name SRCFILE. */
+/* Like collect_symbol_completion_matches, but collects a list of
+ symbols defined in all source files named SRCFILE. */
-static VEC (char_ptr) *
-make_file_symbol_completion_list_1 (const char *text, const char *word,
- const char *srcfile)
+void
+collect_file_symbol_completion_matches (completion_tracker &tracker,
+ const char *text, const char *word,
+ const char *srcfile)
{
/* The symbol we are completing on. Points in same buffer as text. */
const char *sym_text;
@@ -5345,7 +5291,7 @@ make_file_symbol_completion_list_1 (const char *text, const char *word,
/* A double-quoted string is never a symbol, nor does it make sense
to complete it any other way. */
{
- return NULL;
+ return;
}
else
{
@@ -5361,42 +5307,11 @@ make_file_symbol_completion_list_1 (const char *text, const char *word,
iterate_over_symtabs (srcfile, [&] (symtab *s)
{
add_symtab_completions (SYMTAB_COMPUNIT (s),
+ tracker,
sym_text, sym_text_len,
text, word, TYPE_CODE_UNDEF);
return false;
});
-
- return (return_val);
-}
-
-/* Wrapper around make_file_symbol_completion_list_1
- to handle MAX_COMPLETIONS_REACHED_ERROR. */
-
-VEC (char_ptr) *
-make_file_symbol_completion_list (const char *text, const char *word,
- const char *srcfile)
-{
- struct cleanup *back_to, *cleanups;
-
- completion_tracker = new_completion_tracker ();
- cleanups = make_cleanup_free_completion_tracker (&completion_tracker);
- return_val = NULL;
- back_to = make_cleanup (do_free_completion_list, &return_val);
-
- TRY
- {
- make_file_symbol_completion_list_1 (text, word, srcfile);
- }
- CATCH (except, RETURN_MASK_ERROR)
- {
- if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
- throw_exception (except);
- }
- END_CATCH
-
- discard_cleanups (back_to);
- do_cleanups (cleanups);
- return return_val;
}
/* A helper function for make_source_files_completion_list. It adds
@@ -5405,7 +5320,7 @@ make_file_symbol_completion_list (const char *text, const char *word,
static void
add_filename_to_list (const char *fname, const char *text, const char *word,
- VEC (char_ptr) **list)
+ completion_list *list)
{
char *newobj;
size_t fnlen = strlen (fname);
@@ -5430,7 +5345,7 @@ add_filename_to_list (const char *fname, const char *text, const char *word,
newobj[text - word] = '\0';
strcat (newobj, fname);
}
- VEC_safe_push (char_ptr, *list, newobj);
+ list->emplace_back (newobj);
}
static int
@@ -5458,7 +5373,7 @@ struct add_partial_filename_data
const char *text;
const char *word;
int text_len;
- VEC (char_ptr) **list;
+ completion_list *list;
};
/* A callback for map_partial_symbol_filenames. */
@@ -5490,19 +5405,18 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
}
}
-/* Return a vector of all source files whose names begin with matching
+/* Return a list of all source files whose names begin with matching
TEXT. The file names are looked up in the symbol tables of this
- program. If the answer is no matchess, then the return value is
- NULL. */
+ program. */
-VEC (char_ptr) *
+completion_list
make_source_files_completion_list (const char *text, const char *word)
{
struct compunit_symtab *cu;
struct symtab *s;
struct objfile *objfile;
size_t text_len = strlen (text);
- VEC (char_ptr) *list = NULL;
+ completion_list list;
const char *base_name;
struct add_partial_filename_data datum;
struct cleanup *back_to;
@@ -5510,8 +5424,6 @@ make_source_files_completion_list (const char *text, const char *word)
if (!have_full_symbols () && !have_partial_symbols ())
return list;
- back_to = make_cleanup (do_free_completion_list, &list);
-
filename_seen_cache filenames_seen;
ALL_FILETABS (objfile, cu, s)
@@ -5547,8 +5459,6 @@ make_source_files_completion_list (const char *text, const char *word)
map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
0 /*need_fullname*/);
- discard_cleanups (back_to);
-
return list;
}