/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include <ctype.h>
#include "cp-abi.h"
#include "cp-support.h"
-#include "observer.h"
+#include "observable.h"
#include "solist.h"
#include "macrotab.h"
#include "macroscope.h"
#include "filename-seen-cache.h"
#include "arch-utils.h"
#include <algorithm>
+#include "common/pathstuff.h"
/* Forward declarations for local functions. */
static struct block_symbol
lookup_symbol_aux (const char *name,
+ symbol_name_match_type match_type,
const struct block *block,
const domain_enum domain,
enum language language,
static
struct block_symbol lookup_local_symbol (const char *name,
+ symbol_name_match_type match_type,
const struct block *block,
const domain_enum domain,
enum language language);
{
char *demangled = NULL;
int i;
- int recognized;
if (gsymbol->language == language_unknown)
gsymbol->language = language_auto;
const lookup_name_info &name)
{
symbol_name_matcher_ftype *name_match
- = language_get_symbol_name_matcher (language_def (gsymbol->language),
- name);
+ = get_symbol_name_matcher (language_def (gsymbol->language), name);
return name_match (symbol_search_name (gsymbol), name, NULL);
}
if (without_params != NULL)
{
- m_demangled_name = demangle_for_lookup (without_params.get (),
- lang, storage);
+ if (lookup_name.match_type () != symbol_name_match_type::SEARCH_NAME)
+ m_demangled_name = demangle_for_lookup (without_params.get (),
+ lang, storage);
return;
}
}
- m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (),
- lang, storage);
+ if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
+ m_demangled_name = lookup_name.name ();
+ else
+ m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (),
+ lang, storage);
}
/* See symtab.h. */
demangle_result_storage storage;
const char *modified_name = demangle_for_lookup (name, lang, storage);
- return lookup_symbol_aux (modified_name, block, domain, lang,
+ return lookup_symbol_aux (modified_name,
+ symbol_name_match_type::FULL,
+ block, domain, lang,
is_a_field_of_this);
}
/* See symtab.h. */
+struct block_symbol
+lookup_symbol_search_name (const char *search_name, const struct block *block,
+ domain_enum domain)
+{
+ return lookup_symbol_aux (search_name, symbol_name_match_type::SEARCH_NAME,
+ block, domain, language_asm, NULL);
+}
+
+/* See symtab.h. */
+
struct block_symbol
lookup_language_this (const struct language_defn *lang,
const struct block *block)
{
struct symbol *sym;
- sym = block_lookup_symbol (block, lang->la_name_of_this, VAR_DOMAIN);
+ sym = block_lookup_symbol (block, lang->la_name_of_this,
+ symbol_name_match_type::SEARCH_NAME,
+ VAR_DOMAIN);
if (sym != NULL)
{
if (symbol_lookup_debug > 1)
(e.g., demangled name) of the symbol that we're looking for. */
static struct block_symbol
-lookup_symbol_aux (const char *name, const struct block *block,
+lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
+ const struct block *block,
const domain_enum domain, enum language language,
struct field_of_this_result *is_a_field_of_this)
{
/* Search specified block and its superiors. Don't search
STATIC_BLOCK or GLOBAL_BLOCK. */
- result = lookup_local_symbol (name, block, domain, language);
+ result = lookup_local_symbol (name, match_type, block, domain, language);
if (result.symbol != NULL)
{
if (symbol_lookup_debug)
Don't search STATIC_BLOCK or GLOBAL_BLOCK. */
static struct block_symbol
-lookup_local_symbol (const char *name, const struct block *block,
+lookup_local_symbol (const char *name,
+ symbol_name_match_type match_type,
+ const struct block *block,
const domain_enum domain,
enum language language)
{
while (block != static_block)
{
- sym = lookup_symbol_in_block (name, block, domain);
+ sym = lookup_symbol_in_block (name, match_type, block, domain);
if (sym != NULL)
return (struct block_symbol) {sym, block};
/* See symtab.h. */
struct symbol *
-lookup_symbol_in_block (const char *name, const struct block *block,
+lookup_symbol_in_block (const char *name, symbol_name_match_type match_type,
+ const struct block *block,
const domain_enum domain)
{
struct symbol *sym;
domain_name (domain));
}
- sym = block_lookup_symbol (block, name, domain);
+ sym = block_lookup_symbol (block, name, match_type, domain);
if (sym)
{
if (symbol_lookup_debug > 1)
bv = COMPUNIT_BLOCKVECTOR (cust);
block = BLOCKVECTOR_BLOCK (bv, block_index);
- result.symbol = block_lookup_symbol (block, name, domain);
+ result.symbol = block_lookup_symbol (block, name,
+ symbol_name_match_type::FULL, domain);
if (result.symbol == NULL)
error_in_psymtab_expansion (block_index, name, cust);
domain_name (domain));
}
- sym = lookup_symbol_in_block (name, static_block, domain);
+ sym = lookup_symbol_in_block (name,
+ symbol_name_match_type::FULL,
+ static_block, domain);
if (symbol_lookup_debug)
{
fprintf_unfiltered (gdb_stdlog,
{
return find_pc_sect_compunit_symtab (pc, find_pc_mapped_section (pc));
}
+
+/* See symtab.h. */
+
+struct symbol *
+find_symbol_at_address (CORE_ADDR address)
+{
+ struct objfile *objfile;
+
+ ALL_OBJFILES (objfile)
+ {
+ if (objfile->sf == NULL
+ || objfile->sf->qf->find_compunit_symtab_by_address == NULL)
+ continue;
+
+ struct compunit_symtab *symtab
+ = objfile->sf->qf->find_compunit_symtab_by_address (objfile, address);
+ if (symtab != NULL)
+ {
+ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab);
+
+ for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
+ {
+ struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+ struct block_iterator iter;
+ struct symbol *sym;
+
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ if (SYMBOL_CLASS (sym) == LOC_STATIC
+ && SYMBOL_VALUE_ADDRESS (sym) == address)
+ return sym;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
\f
/* Find the source file and line number for a given PC value and SECTION.
find the one whose first PC is closer than that of the next line in this
symtab. */
-/* If it's worth the effort, we could be using a binary search. */
-
struct symtab_and_line
find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
{
if (item->pc > pc && (!alt || item->pc < alt->pc))
alt = item;
- for (i = 0; i < len; i++, item++)
- {
- /* Leave prev pointing to the linetable entry for the last line
- that started at or before PC. */
- if (item->pc > pc)
- break;
+ auto pc_compare = [](const CORE_ADDR & pc,
+ const struct linetable_entry & lhs)->bool
+ {
+ return pc < lhs.pc;
+ };
- prev = item;
- }
+ struct linetable_entry *first = item;
+ struct linetable_entry *last = item + len;
+ item = std::upper_bound (first, last, pc, pc_compare);
+ if (item != first)
+ prev = item - 1; /* Found a matching item. */
/* At this point, prev points at the line whose start addr is <= pc, and
item points at the next line. If we ran off the end of the linetable
}
/* If another line (denoted by ITEM) is in the linetable and its
- PC is after BEST's PC, but before the current BEST_END, then
+ PC is after BEST's PC, but before the current BEST_END, then
use ITEM's PC as the new best_end. */
- if (best && i < len && item->pc > best->pc
- && (best_end == 0 || best_end > item->pc))
+ if (best && item < last && item->pc > best->pc
+ && (best_end == 0 || best_end > item->pc))
best_end = item->pc;
}
symbol *
find_function_alias_target (bound_minimal_symbol msymbol)
{
- if (!msymbol_is_text (msymbol.minsym))
+ CORE_ADDR func_addr;
+ if (!msymbol_is_function (msymbol.objfile, msymbol.minsym, &func_addr))
return NULL;
- CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
- symbol *sym = find_pc_function (addr);
+ symbol *sym = find_pc_function (func_addr);
if (sym != NULL
&& SYMBOL_CLASS (sym) == LOC_BLOCK
- && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == addr)
+ && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == func_addr)
return sym;
return NULL;
and <TYPENAME> or <OPERATOR>. */
const char *opend;
const char *opname = operator_chars (regexp, &opend);
- int errcode;
if (*opname)
{
const lookup_name_info &lookup_name,
completion_match_result &match_res)
{
- const language_defn *lang;
-
- /* If we're completing for an expression and the symbol doesn't have
- an explicit language set, fallback to the current language. Ada
- minimal symbols won't have their language set to Ada, for
- example, and if we compared using the default/C-like matcher,
- then when completing e.g., symbols in a package named "pck", we'd
- match internal Ada symbols like "pckS", which are invalid in an
- Ada expression, unless you wrap them in '<' '>' to request a
- verbatim match. */
- if (symbol_language == language_auto
- && lookup_name.match_type () == symbol_name_match_type::EXPRESSION)
- lang = current_language;
- else
- lang = language_def (symbol_language);
+ const language_defn *lang = language_def (symbol_language);
symbol_name_matcher_ftype *name_match
- = language_get_symbol_name_matcher (lang, lookup_name);
+ = get_symbol_name_matcher (lang, lookup_name);
- return name_match (symbol_name, lookup_name, &match_res.match);
+ return name_match (symbol_name, lookup_name, &match_res);
}
/* See symtab.h. */
of matches. Note that the name is moved to freshly malloc'd space. */
{
- char *newobj;
-
- if (word == text)
- {
- newobj = (char *) xmalloc (strlen (symname) + 5);
- strcpy (newobj, symname);
- }
- else if (word > text)
- {
- /* Return some portion of symname. */
- newobj = (char *) xmalloc (strlen (symname) + 5);
- strcpy (newobj, symname + (word - text));
- }
- else
- {
- /* Return some of SYM_TEXT plus symname. */
- newobj = (char *) xmalloc (strlen (symname) + (text - word) + 5);
- strncpy (newobj, word, text - word);
- newobj[text - word] = '\0';
- strcat (newobj, symname);
- }
-
- gdb::unique_xmalloc_ptr<char> completion (newobj);
-
- tracker.add_completion (std::move (completion));
+ gdb::unique_xmalloc_ptr<char> completion
+ = make_completion_match_str (symname, text, word);
+
+ /* Here we pass the match-for-lcd object to add_completion. Some
+ languages match the user text against substrings of symbol
+ names in some cases. E.g., in C++, "b push_ba" completes to
+ "std::vector::push_back", "std::string::push_back", etc., and
+ in this case we want the completion lowest common denominator
+ to be "push_back" instead of "std::". */
+ tracker.add_completion (std::move (completion),
+ &match_res.match_for_lcd, text, word);
}
}
}
}
+/* See symtab.h. */
+
+bool
+symbol_is_function_or_method (symbol *sym)
+{
+ switch (TYPE_CODE (SYMBOL_TYPE (sym)))
+ {
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_METHOD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* See symtab.h. */
+
+bool
+symbol_is_function_or_method (minimal_symbol *msymbol)
+{
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_text:
+ case mst_text_gnu_ifunc:
+ case mst_solib_trampoline:
+ case mst_file_text:
+ return true;
+ default:
+ return false;
+ }
+}
+
/* Add matching symbols from SYMTAB to the current completion list. */
static void
add_symtab_completions (struct compunit_symtab *cust,
completion_tracker &tracker,
+ complete_symbol_mode mode,
const lookup_name_info &lookup_name,
const char *text, const char *word,
enum type_code code)
b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), i);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
+ if (completion_skip_symbol (mode, sym))
+ continue;
+
if (code == TYPE_CODE_UNDEF
|| (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
&& TYPE_CODE (SYMBOL_TYPE (sym)) == code))
{
QUIT;
+ if (completion_skip_symbol (mode, msymbol))
+ continue;
+
completion_list_add_msymbol (tracker, msymbol, lookup_name,
sym_text, word);
/* Add completions for all currently loaded symbol tables. */
ALL_COMPUNITS (objfile, cust)
- add_symtab_completions (cust, tracker, lookup_name,
+ add_symtab_completions (cust, tracker, mode, lookup_name,
sym_text, word, code);
/* Look through the partial symtabs for all symbols which begin by
[&] (compunit_symtab *symtab) /* expansion notify */
{
add_symtab_completions (symtab,
- tracker, lookup_name,
+ tracker, mode, lookup_name,
sym_text, word, code);
},
ALL_DOMAIN);
if (current_language->la_macro_expansion == macro_expansion_c
&& code == TYPE_CODE_UNDEF)
{
- struct macro_scope *scope;
+ gdb::unique_xmalloc_ptr<struct macro_scope> scope;
/* This adds a macro's name to the current completion list. */
auto add_macro_name = [&] (const char *macro_name,
completion time. */
scope = default_macro_scope ();
if (scope)
- {
- macro_for_each_in_scope (scope->file, scope->line,
- add_macro_name);
- xfree (scope);
- }
+ macro_for_each_in_scope (scope->file, scope->line,
+ add_macro_name);
/* User-defined macros are always visible. */
macro_for_each (macro_user_macros, add_macro_name);
iterate_over_symtabs (srcfile, [&] (symtab *s)
{
add_symtab_completions (SYMTAB_COMPUNIT (s),
- tracker, lookup_name,
+ tracker, mode, lookup_name,
sym_text, word, TYPE_CODE_UNDEF);
return false;
});
add_filename_to_list (const char *fname, const char *text, const char *word,
completion_list *list)
{
- char *newobj;
- size_t fnlen = strlen (fname);
-
- if (word == text)
- {
- /* Return exactly fname. */
- newobj = (char *) xmalloc (fnlen + 5);
- strcpy (newobj, fname);
- }
- else if (word > text)
- {
- /* Return some portion of fname. */
- newobj = (char *) xmalloc (fnlen + 5);
- strcpy (newobj, fname + (word - text));
- }
- else
- {
- /* Return some of TEXT plus fname. */
- newobj = (char *) xmalloc (fnlen + (text - word) + 5);
- strncpy (newobj, word, text - word);
- newobj[text - word] = '\0';
- strcat (newobj, fname);
- }
- list->emplace_back (newobj);
+ list->emplace_back (make_completion_match_str (fname, text, word));
}
static int
struct template_symbol *result;
result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol);
- initialize_objfile_symbol_1 (&result->base);
+ initialize_objfile_symbol_1 (result);
return result;
}
_("Flush the symbol cache for each program space."),
&maintenancelist);
- observer_attach_executable_changed (symtab_observer_executable_changed);
- observer_attach_new_objfile (symtab_new_objfile_observer);
- observer_attach_free_objfile (symtab_free_objfile_observer);
+ gdb::observers::executable_changed.attach (symtab_observer_executable_changed);
+ gdb::observers::new_objfile.attach (symtab_new_objfile_observer);
+ gdb::observers::free_objfile.attach (symtab_free_objfile_observer);
}