#include "symfile.h"
#include "objfiles.h"
#include "gdbcmd.h"
-#include "call-cmds.h"
#include "gdb_regex.h"
#include "expression.h"
#include "language.h"
#include "macroscope.h"
#include "psymtab.h"
+#include "parser-defs.h"
/* Prototypes for local functions */
const struct block *block,
const domain_enum domain,
enum language language,
- int *is_a_field_of_this);
+ struct field_of_this_result *is_a_field_of_this);
static
struct symbol *lookup_symbol_aux_local (const char *name,
/* See whether FILENAME matches SEARCH_NAME using the rule that we
advertise to the user. (The manual's description of linespecs
- describes what we advertise). SEARCH_LEN is the length of
- SEARCH_NAME. We assume that SEARCH_NAME is a relative path.
- Returns true if they match, false otherwise. */
+ describes what we advertise). We assume that SEARCH_NAME is
+ a relative path. Returns true if they match, false otherwise. */
int
-compare_filenames_for_search (const char *filename, const char *search_name,
- int search_len)
+compare_filenames_for_search (const char *filename, const char *search_name)
{
int len = strlen (filename);
+ size_t search_len = strlen (search_name);
if (len < search_len)
return 0;
{
struct symtab *s = NULL;
const char* base_name = lbasename (name);
- int name_len = strlen (name);
int is_abs = IS_ABSOLUTE_PATH (name);
for (s = first; s != NULL && s != after_last; s = s->next)
return 1;
}
- if (!is_abs && compare_filenames_for_search (s->filename, name, name_len))
+ if (!is_abs && compare_filenames_for_search (s->filename, name))
{
if (callback (s, data))
return 1;
{
const char *fp = symtab_to_fullname (s);
- if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+ if (FILENAME_CMP (full_path, fp) == 0)
{
if (callback (s, data))
return 1;
}
- if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name,
- name_len))
+ if (!is_abs && compare_filenames_for_search (fp, name))
{
if (callback (s, data))
return 1;
if (real_path != NULL)
{
- char *fullname = symtab_to_fullname (s);
+ const char *fullname = symtab_to_fullname (s);
+ char *rp = gdb_realpath (fullname);
- if (fullname != NULL)
- {
- char *rp = gdb_realpath (fullname);
-
- make_cleanup (xfree, rp);
- if (FILENAME_CMP (real_path, rp) == 0)
- {
- if (callback (s, data))
- return 1;
- }
+ make_cleanup (xfree, rp);
+ if (FILENAME_CMP (real_path, rp) == 0)
+ {
+ if (callback (s, data))
+ return 1;
+ }
- if (!is_abs && compare_filenames_for_search (rp, name, name_len))
- {
- if (callback (s, data))
- return 1;
- }
- }
+ if (!is_abs && compare_filenames_for_search (rp, name))
+ {
+ if (callback (s, data))
+ return 1;
+ }
}
}
if (len == 0)
{
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
}
else if (physname[0] == 't' || physname[0] == 'Q')
{
/* The physname for template and qualified methods already includes
the class name. */
- sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
newname = NULL;
len = 0;
}
else
{
- sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+ xsnprintf (buf, sizeof (buf), "__%s%s%d", const_prefix,
+ volatile_prefix, len);
}
mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
+ strlen (buf) + len + strlen (physname) + 1);
struct symbol *
lookup_symbol_in_language (const char *name, const struct block *block,
const domain_enum domain, enum language lang,
- int *is_a_field_of_this)
+ struct field_of_this_result *is_a_field_of_this)
{
const char *modified_name;
struct symbol *returnval;
struct symbol *
lookup_symbol (const char *name, const struct block *block,
- domain_enum domain, int *is_a_field_of_this)
+ domain_enum domain,
+ struct field_of_this_result *is_a_field_of_this)
{
return lookup_symbol_in_language (name, block, domain,
current_language->la_language,
return NULL;
}
+/* Given TYPE, a structure/union,
+ return 1 if the component named NAME from the ultimate target
+ structure/union is defined, otherwise, return 0. */
+
+static int
+check_field (struct type *type, const char *name,
+ struct field_of_this_result *is_a_field_of_this)
+{
+ int i;
+
+ /* The type may be a stub. */
+ CHECK_TYPEDEF (type);
+
+ for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+ {
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
+
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+ {
+ is_a_field_of_this->type = type;
+ is_a_field_of_this->field = &TYPE_FIELD (type, i);
+ return 1;
+ }
+ }
+
+ /* C++: If it was not found as a data field, then try to return it
+ as a pointer to a method. */
+
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
+ {
+ if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0)
+ {
+ is_a_field_of_this->type = type;
+ is_a_field_of_this->fn_field = &TYPE_FN_FIELDLIST (type, i);
+ return 1;
+ }
+ }
+
+ for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+ if (check_field (TYPE_BASECLASS (type, i), name, is_a_field_of_this))
+ return 1;
+
+ return 0;
+}
+
/* Behave like lookup_symbol except that NAME is the natural name
(e.g., demangled name) of the symbol that we're looking for. */
static struct symbol *
lookup_symbol_aux (const char *name, const struct block *block,
const domain_enum domain, enum language language,
- int *is_a_field_of_this)
+ struct field_of_this_result *is_a_field_of_this)
{
struct symbol *sym;
const struct language_defn *langdef;
/* 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 and expect it to be either 0 or 1.
- If we don't set it, the contents of is_a_field_of_this are
- undefined. */
+ certainly use it later. If we don't set it, the contents of
+ is_a_field_of_this are undefined. */
if (is_a_field_of_this != NULL)
- *is_a_field_of_this = 0;
+ memset (is_a_field_of_this, 0, sizeof (*is_a_field_of_this));
/* Search specified block and its superiors. Don't search
STATIC_BLOCK or GLOBAL_BLOCK. */
langdef = language_def (language);
- if (is_a_field_of_this != NULL)
+ /* Don't do this check if we are searching for a struct. It will
+ not be found by check_field, but will be found by other
+ means. */
+ if (is_a_field_of_this != NULL && domain != STRUCT_DOMAIN)
{
struct symbol *sym = lookup_language_this (langdef, block);
error (_("Internal error: `%s' is not an aggregate"),
langdef->la_name_of_this);
- if (check_field (t, name))
- {
- *is_a_field_of_this = 1;
- return NULL;
- }
+ if (check_field (t, name, is_a_field_of_this))
+ return NULL;
}
}
lookup_data.name = name;
lookup_data.domain = domain;
gdbarch_iterate_over_objfiles_in_search_order
- (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch,
+ (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch (),
lookup_symbol_global_iterator_cb, &lookup_data, objfile);
return lookup_data.result;
if (best_s != NULL)
return (best_s);
+ /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs). */
+
ALL_OBJFILES (objfile)
{
struct symtab *result;
symtab->filename);
}
- /* Get symbol full file name if possible. */
- symtab_to_fullname (symtab);
-
ALL_SYMTABS (objfile, s)
{
struct linetable *l;
if (FILENAME_CMP (symtab->filename, s->filename) != 0)
continue;
- if (symtab->fullname != NULL
- && symtab_to_fullname (s) != NULL
- && FILENAME_CMP (symtab->fullname, s->fullname) != 0)
+ if (FILENAME_CMP (symtab->fullname, symtab_to_fullname (s)) != 0)
continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact, 0);
struct block *b, *function_block;
int force_skip, skip;
- /* Do not change the SAL is PC was specified explicitly. */
+ /* Do not change the SAL if PC was specified explicitly. */
if (sal->explicit_pc)
return;
struct filename_seen_cache
{
/* Table of files seen so far. */
- const char **tab;
-
- /* Allocated size of tab in elements. */
- int tab_alloc_size;
+ htab_t tab;
+ /* Initial size of the table. It automagically grows from here. */
#define INITIAL_FILENAME_SEEN_CACHE_SIZE 100
-
- /* Current size of tab in elements. */
- int tab_cur_size;
};
/* filename_seen_cache constructor. */
struct filename_seen_cache *cache;
cache = XNEW (struct filename_seen_cache);
- cache->tab_alloc_size = INITIAL_FILENAME_SEEN_CACHE_SIZE;
- cache->tab = XNEWVEC (const char *, cache->tab_alloc_size);
- cache->tab_cur_size = 0;
+ 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)
+clear_filename_seen_cache (struct filename_seen_cache *cache)
{
- cache->tab_cur_size = 0;
+ htab_empty (cache->tab);
}
/* filename_seen_cache destructor.
{
struct filename_seen_cache *cache = ptr;
- xfree (cache->tab);
+ 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. */
+ 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)
{
- const char **p;
+ void **slot;
/* Is FILE in tab? */
- for (p = cache->tab; p < cache->tab + cache->tab_cur_size; p++)
- if (filename_cmp (*p, file) == 0)
- return 1;
+ slot = htab_find_slot (cache->tab, file, add ? INSERT : NO_INSERT);
+ if (*slot != NULL)
+ return 1;
/* No; maybe add it to tab. */
if (add)
- {
- if (cache->tab_cur_size == cache->tab_alloc_size)
- {
- cache->tab_alloc_size *= 2;
- cache->tab = XRESIZEVEC (const char *, cache->tab,
- cache->tab_alloc_size);
- }
- cache->tab[cache->tab_cur_size++] = file;
- }
+ *slot = (char *) file;
return 0;
}
{
const char *fullname = symtab_to_fullname (s);
- output_source_filename (fullname ? fullname : s->filename, &data);
+ output_source_filename (fullname, &data);
}
printf_filtered ("\n\n");
search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
old_chain = make_cleanup_free_search_symbols (symbols);
- printf_filtered (regexp
- ? "All %ss matching regular expression \"%s\":\n"
- : "All defined %ss:\n",
- classnames[kind], regexp);
+ if (regexp != NULL)
+ printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
+ classnames[kind], regexp);
+ else
+ printf_filtered (_("All defined %ss:\n"), classnames[kind]);
for (p = symbols; p != NULL; p = p->next)
{
{
if (first)
{
- printf_filtered ("\nNon-debugging symbols:\n");
+ printf_filtered (_("\nNon-debugging symbols:\n"));
first = 0;
}
print_msymbol_info (p->msymbol);
VEC (char_ptr) *
default_make_symbol_completion_list_break_on (char *text, char *word,
- const char *break_on)
+ 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
anything that isn't a text symbol (everything else will be
handled by the psymtab code above). */
- ALL_MSYMBOLS (objfile, msymbol)
- {
- QUIT;
- COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+ if (code == TYPE_CODE_UNDEF)
+ {
+ ALL_MSYMBOLS (objfile, msymbol)
+ {
+ QUIT;
+ COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text,
+ word);
- completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word);
- }
+ completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text,
+ word);
+ }
+ }
/* Search upwards from currently selected frame (so that we can
complete on local vars). Also catch fields of types defined in
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
- word);
- completion_list_add_fields (sym, sym_text, sym_text_len, text,
- word);
+ if (code == TYPE_CODE_UNDEF)
+ {
+ 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,
+ word);
}
/* Stop when we encounter an enclosing function. Do not stop for
/* Add fields from the file's types; symbols will be added below. */
- 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);
+ if (code == TYPE_CODE_UNDEF)
+ {
+ 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);
- 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);
+ 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);
+ }
/* Go through the symtabs and check the externs and statics for
symbols which match. */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ if (code == TYPE_CODE_UNDEF
+ || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
}
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+ if (code == TYPE_CODE_UNDEF
+ || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
}
}
- if (current_language->la_macro_expansion == macro_expansion_c)
+ /* Skip macros if we are completing a struct tag -- arguable but
+ usually what is expected. */
+ if (current_language->la_macro_expansion == macro_expansion_c
+ && code == TYPE_CODE_UNDEF)
{
struct macro_scope *scope;
}
VEC (char_ptr) *
-default_make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list (char *text, char *word,
+ enum type_code code)
{
- return default_make_symbol_completion_list_break_on (text, word, "");
+ return default_make_symbol_completion_list_break_on (text, word, "", code);
}
/* Return a vector of all symbols (regardless of class) which begin by
VEC (char_ptr) *
make_symbol_completion_list (char *text, char *word)
{
- return current_language->la_make_symbol_completion_list (text, word);
+ return current_language->la_make_symbol_completion_list (text, word,
+ TYPE_CODE_UNDEF);
+}
+
+/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN
+ symbols whose type code is CODE. */
+
+VEC (char_ptr) *
+make_symbol_completion_type (char *text, char *word, enum type_code code)
+{
+ gdb_assert (code == TYPE_CODE_UNION
+ || code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_CLASS
+ || code == TYPE_CODE_ENUM);
+ return current_language->la_make_symbol_completion_list (text, word, code);
}
/* Like make_symbol_completion_list, but suitable for use as a