/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 Free Software Foundation, Inc.
This file is part of GDB.
#include "symfile.h"
#include "objfiles.h"
#include "gdbcmd.h"
-#include "gdb_regex.h"
+#include "gdbsupport/gdb_regex.h"
#include "expression.h"
#include "language.h"
#include "demangle.h"
#include "addrmap.h"
#include "cli/cli-utils.h"
#include "cli/cli-style.h"
+#include "cli/cli-cmds.h"
#include "fnmatch.h"
#include "hashtab.h"
#include "typeprint.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
#include "block.h"
#include "dictionary.h"
/* See symtab.h. */
+program_space *
+symtab::pspace () const
+{
+ return this->objfile ()->pspace;
+}
+
+/* See symtab.h. */
+
+call_site *
+compunit_symtab::find_call_site (CORE_ADDR pc) const
+{
+ if (m_call_site_htab == nullptr)
+ return nullptr;
+
+ CORE_ADDR delta
+ = this->objfile ()->section_offsets[this->block_line_section ()];
+ CORE_ADDR unrelocated_pc = pc - delta;
+
+ struct call_site call_site_local (unrelocated_pc, nullptr, nullptr);
+ void **slot
+ = htab_find_slot (m_call_site_htab, &call_site_local, NO_INSERT);
+ if (slot == nullptr)
+ return nullptr;
+
+ return (call_site *) *slot;
+}
+
+/* See symtab.h. */
+
+void
+compunit_symtab::set_call_site_htab (htab_t call_site_htab)
+{
+ gdb_assert (m_call_site_htab == nullptr);
+ m_call_site_htab = call_site_htab;
+}
+
+/* See symtab.h. */
+
+void
+compunit_symtab::set_primary_filetab (symtab *primary_filetab)
+{
+ symtab *prev_filetab = nullptr;
+
+ /* Move PRIMARY_FILETAB to the head of the filetab list. */
+ for (symtab *filetab : this->filetabs ())
+ {
+ if (filetab == primary_filetab)
+ {
+ if (prev_filetab != nullptr)
+ {
+ prev_filetab->next = primary_filetab->next;
+ primary_filetab->next = m_filetabs;
+ m_filetabs = primary_filetab;
+ }
+
+ break;
+ }
+
+ prev_filetab = filetab;
+ }
+
+ gdb_assert (primary_filetab == m_filetabs);
+}
+
+/* See symtab.h. */
+
struct symtab *
-compunit_primary_filetab (const struct compunit_symtab *cust)
+compunit_symtab::primary_filetab () const
{
- gdb_assert (COMPUNIT_FILETABS (cust) != NULL);
+ gdb_assert (m_filetabs != nullptr);
/* The primary file symtab is the first one in the list. */
- return COMPUNIT_FILETABS (cust);
+ return m_filetabs;
}
/* See symtab.h. */
enum language
compunit_language (const struct compunit_symtab *cust)
{
- struct symtab *symtab = compunit_primary_filetab (cust);
+ struct symtab *symtab = cust->primary_filetab ();
/* The language of the compunit symtab is the language of its primary
source file. */
- return SYMTAB_LANGUAGE (symtab);
+ return symtab->language ();
}
/* See symtab.h. */
for (cust = first; cust != NULL && cust != after_last; cust = cust->next)
{
- for (symtab *s : compunit_filetabs (cust))
+ for (symtab *s : cust->filetabs ())
{
if (compare_filenames_for_search (s->filename, name))
{
for (objfile *objfile : current_program_space->objfiles ())
{
- if (objfile->sf
- && objfile->sf->qf->map_symtabs_matching_filename (objfile,
- name,
- real_path.get (),
- callback))
+ if (objfile->map_symtabs_matching_filename (name, real_path.get (),
+ callback))
return;
}
}
else if (physname[0] == 't' || physname[0] == 'Q')
{
/* The physname for template and qualified methods already includes
- the class name. */
+ the class name. */
xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
newname = NULL;
len = 0;
/* See symtab.h */
-char *
+gdb::unique_xmalloc_ptr<char>
symbol_find_demangled_name (struct general_symbol_info *gsymbol,
const char *mangled)
{
- char *demangled = NULL;
+ gdb::unique_xmalloc_ptr<char> demangled;
int i;
if (gsymbol->language () == language_unknown)
{
const struct language_defn *lang = language_def (gsymbol->language ());
- language_sniff_from_mangled_name (lang, mangled, &demangled);
+ lang->sniff_from_mangled_name (mangled, &demangled);
return demangled;
}
enum language l = (enum language) i;
const struct language_defn *lang = language_def (l);
- if (language_sniff_from_mangled_name (lang, mangled, &demangled))
+ if (lang->sniff_from_mangled_name (mangled, &demangled))
{
gsymbol->m_language = l;
return demangled;
if (language () == language_ada)
{
/* In Ada, we do the symbol lookups using the mangled name, so
- we can save some space by not storing the demangled name. */
+ we can save some space by not storing the demangled name. */
if (!copy_name)
m_name = linkage_name.data ();
else
if (!hash.has_value ())
hash = hash_demangled_name_entry (&entry);
slot = ((struct demangled_name_entry **)
- htab_find_slot_with_hash (per_bfd->demangled_names_hash.get (),
+ htab_find_slot_with_hash (per_bfd->demangled_names_hash.get (),
&entry, *hash, INSERT));
/* The const_cast is safe because the only reason it is already
|| (language () == language_go && (*slot)->demangled == nullptr))
{
/* A 0-terminated copy of the linkage name. Callers must set COPY_NAME
- to true if the string might not be nullterminated. We have to make
- this copy because demangling needs a nullterminated string. */
+ to true if the string might not be nullterminated. We have to make
+ this copy because demangling needs a nullterminated string. */
gdb::string_view linkage_name_copy;
if (copy_name)
{
linkage_name_copy = linkage_name;
if (demangled_name.get () == nullptr)
- demangled_name.reset
- (symbol_find_demangled_name (this, linkage_name_copy.data ()));
+ demangled_name
+ = symbol_find_demangled_name (this, linkage_name_copy.data ());
/* Suppose we have demangled_name==NULL, copy_name==0, and
linkage_name_copy==linkage_name. In this case, we already have the
/* See symtab.h. */
+struct obj_section *
+general_symbol_info::obj_section (const struct objfile *objfile) const
+{
+ if (section_index () >= 0)
+ return &objfile->sections[section_index ()];
+ return nullptr;
+}
+
+/* See symtab.h. */
+
bool
symbol_matches_search_name (const struct general_symbol_info *gsymbol,
const lookup_name_info &name)
{
symbol_name_matcher_ftype *name_match
- = get_symbol_name_matcher (language_def (gsymbol->language ()), name);
+ = language_def (gsymbol->language ())->get_symbol_name_matcher (name);
return name_match (gsymbol->search_name (), name, NULL);
}
for (objfile *objfile : current_program_space->objfiles ())
{
- struct compunit_symtab *cust = NULL;
-
- if (objfile->sf)
- cust = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile, msymbol,
- pc, section, 0);
+ struct compunit_symtab *cust
+ = objfile->find_pc_sect_compunit_symtab (msymbol, pc, section, 0);
if (cust)
return;
}
else
{
slot_name = slot->value.found.symbol->search_name ();
- slot_domain = SYMBOL_DOMAIN (slot->value.found.symbol);
+ slot_domain = slot->value.found.symbol->domain ();
}
/* NULL names match. */
struct symbol *sym = slot->value.found.symbol;
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
- if (!SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
+ if (!symbol_matches_search_name (sym, lookup_name))
return 0;
if (!symbol_matches_domain (sym->language (), slot_domain, domain))
printf_filtered (" [%4u] = %s, %s %s\n", i,
host_address_to_string (context),
found->print_name (),
- domain_name (SYMBOL_DOMAIN (found)));
+ domain_name (found->domain ()));
break;
}
}
/* If the cache hasn't been created yet, avoid creating one. */
cache = symbol_cache_key.get (pspace);
if (cache == NULL)
- printf_filtered (" empty, no stats available\n");
+ printf_filtered (" empty, no stats available\n");
else
symbol_cache_stats (cache);
}
msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->linkage_name (),
objfile);
if (msym)
- ginfo->section = MSYMBOL_SECTION (msym);
+ ginfo->set_section_index (msym->section_index ());
else
{
/* Static, function-local variables do appear in the linker
if (fallback == -1)
fallback = idx;
- if (obj_section_addr (s) - offset <= addr
- && addr < obj_section_endaddr (s) - offset)
+ if (s->addr () - offset <= addr && addr < s->endaddr () - offset)
{
- ginfo->section = idx;
+ ginfo->set_section_index (idx);
return;
}
}
section. If there is no allocated section, then it hardly
matters what we pick, so just pick zero. */
if (fallback == -1)
- ginfo->section = 0;
+ ginfo->set_section_index (0);
else
- ginfo->section = fallback;
+ ginfo->set_section_index (fallback);
}
}
if (!sym)
return NULL;
- if (!SYMBOL_OBJFILE_OWNED (sym))
+ if (!sym->is_objfile_owned ())
return sym;
/* We either have an OBJFILE, or we can get at it from the sym's
if (objfile == NULL)
objfile = symbol_objfile (sym);
- if (SYMBOL_OBJ_SECTION (objfile, sym))
+ if (sym->obj_section (objfile) != nullptr)
return sym;
/* We should have an objfile by now. */
gdb_assert (objfile);
- switch (SYMBOL_CLASS (sym))
+ switch (sym->aclass ())
{
case LOC_STATIC:
case LOC_LABEL:
lookup, so we can always binary search. */
if (lang == language_cplus)
{
- char *demangled_name = gdb_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ gdb::unique_xmalloc_ptr<char> demangled_name
+ = gdb_demangle (name, DMGL_ANSI | DMGL_PARAMS);
if (demangled_name != NULL)
- return storage.set_malloc_ptr (demangled_name);
+ return storage.set_malloc_ptr (std::move (demangled_name));
/* If we were given a non-mangled name, canonicalize it
according to the language (so far only for C++). */
}
else if (lang == language_d)
{
- char *demangled_name = d_demangle (name, 0);
+ gdb::unique_xmalloc_ptr<char> demangled_name = d_demangle (name, 0);
if (demangled_name != NULL)
- return storage.set_malloc_ptr (demangled_name);
+ return storage.set_malloc_ptr (std::move (demangled_name));
}
else if (lang == language_go)
{
- char *demangled_name = go_demangle (name, 0);
+ gdb::unique_xmalloc_ptr<char> demangled_name
+ = language_def (language_go)->demangle_symbol (name, 0);
if (demangled_name != NULL)
- return storage.set_malloc_ptr (demangled_name);
+ return storage.set_malloc_ptr (std::move (demangled_name));
}
return name;
unsigned int
search_name_hash (enum language language, const char *search_name)
{
- return language_def (language)->la_search_name_hash (search_name);
+ return language_def (language)->search_name_hash (search_name);
}
/* See symtab.h.
lookup_language_this (const struct language_defn *lang,
const struct block *block)
{
- if (lang->la_name_of_this == NULL || block == NULL)
+ if (lang->name_of_this () == NULL || block == NULL)
return {};
if (symbol_lookup_debug > 1)
fprintf_unfiltered (gdb_stdlog,
"lookup_language_this (%s, %s (objfile %s))",
- lang->la_name, host_address_to_string (block),
+ lang->name (), host_address_to_string (block),
objfile_debug_name (objfile));
}
{
struct symbol *sym;
- sym = block_lookup_symbol (block, lang->la_name_of_this,
+ sym = block_lookup_symbol (block, lang->name_of_this (),
symbol_name_match_type::SEARCH_NAME,
VAR_DOMAIN);
if (sym != NULL)
for (i = type->num_fields () - 1; i >= TYPE_N_BASECLASSES (type); i--)
{
- const char *t_field_name = TYPE_FIELD_NAME (type, i);
+ const char *t_field_name = type->field (i).name ();
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);
+ is_a_field_of_this->field = &type->field (i);
return 1;
}
}
if (result.symbol)
{
- struct type *t = result.symbol->type;
+ struct type *t = result.symbol->type ();
/* I'm not really sure that type of this can ever
be typedefed; just be safe. */
t = check_typedef (t);
- if (t->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (t))
+ if (t->is_pointer_or_reference ())
t = TYPE_TARGET_TYPE (t);
if (t->code () != TYPE_CODE_STRUCT
&& t->code () != TYPE_CODE_UNION)
error (_("Internal error: `%s' is not an aggregate"),
- langdef->la_name_of_this);
+ langdef->name_of_this ());
if (check_field (t, name, is_a_field_of_this))
{
/* Now do whatever is appropriate for LANGUAGE to look
up static and global variables. */
- result = langdef->la_lookup_symbol_nonlocal (langdef, name, block, domain);
+ result = langdef->lookup_symbol_nonlocal (name, block, domain);
if (result.symbol != NULL)
{
if (symbol_lookup_debug)
return (struct block_symbol) {sym, block};
if (language == language_cplus || language == language_fortran)
- {
- struct block_symbol blocksym
+ {
+ struct block_symbol blocksym
= cp_lookup_symbol_imports_or_template (scope, name, block,
domain);
- if (blocksym.symbol != NULL)
- return blocksym;
- }
+ if (blocksym.symbol != NULL)
+ return blocksym;
+ }
if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
break;
for (objfile *objfile : main_objfile->separate_debug_objfiles ())
{
struct block_symbol result
- = lookup_symbol_in_objfile (objfile, block_index, name, domain);
+ = lookup_symbol_in_objfile (objfile, block_index, name, domain);
if (result.symbol != nullptr)
return result;
const struct block *block;
struct block_symbol result;
- bv = COMPUNIT_BLOCKVECTOR (cust);
+ bv = cust->blockvector ();
block = BLOCKVECTOR_BLOCK (bv, block_index);
result.symbol = block_lookup_symbol_primary (block, name, domain);
result.block = block;
break;
}
if (symbol_matches_domain (result.symbol->language (),
- SYMBOL_DOMAIN (result.symbol), domain))
+ result.symbol->domain (), domain))
{
struct symbol *better
= better_symbol (other.symbol, result.symbol, domain);
(if a template, try specifying an instantiation: %s<type>)."),
block_index == GLOBAL_BLOCK ? "global" : "static",
name,
- symtab_to_filename_for_display (compunit_primary_filetab (cust)),
+ symtab_to_filename_for_display (cust->primary_filetab ()),
name, name);
}
const struct block *block;
struct block_symbol result;
- if (!objfile->sf)
- return {};
-
if (symbol_lookup_debug > 1)
{
fprintf_unfiltered (gdb_stdlog,
name, domain_name (domain));
}
- cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name, domain);
+ cust = objfile->lookup_symbol (block_index, name, domain);
if (cust == NULL)
{
if (symbol_lookup_debug > 1)
return {};
}
- bv = COMPUNIT_BLOCKVECTOR (cust);
+ bv = cust->blockvector ();
block = BLOCKVECTOR_BLOCK (bv, block_index);
result.symbol = block_lookup_symbol (block, name,
symbol_name_match_type::FULL, domain);
return result;
}
-/* See symtab.h. */
+/* See language.h. */
struct block_symbol
-basic_lookup_symbol_nonlocal (const struct language_defn *langdef,
- const char *name,
- const struct block *block,
- const domain_enum domain)
+language_defn::lookup_symbol_nonlocal (const char *name,
+ const struct block *block,
+ const domain_enum domain) const
{
struct block_symbol result;
gdbarch = target_gdbarch ();
else
gdbarch = block_gdbarch (block);
- result.symbol = language_lookup_primitive_type_as_symbol (langdef,
+ result.symbol = language_lookup_primitive_type_as_symbol (this,
gdbarch, name);
result.block = NULL;
if (result.symbol != NULL)
static enum language
find_quick_global_symbol_language (const char *name, const domain_enum domain)
{
- for (objfile *objfile : current_program_space->objfiles ())
- {
- if (objfile->sf && objfile->sf->qf
- && objfile->sf->qf->lookup_global_symbol_language)
- continue;
- return language_unknown;
- }
-
for (objfile *objfile : current_program_space->objfiles ())
{
bool symbol_found_p;
enum language lang
- = objfile->sf->qf->lookup_global_symbol_language (objfile, name, domain,
- &symbol_found_p);
- if (!symbol_found_p)
- continue;
- return lang;
+ = objfile->lookup_global_symbol_language (name, domain, &symbol_found_p);
+ if (symbol_found_p)
+ return lang;
}
return language_unknown;
struct type *
lookup_transparent_type (const char *name)
{
- return current_language->la_lookup_transparent_type (name);
+ return current_language->lookup_transparent_type (name);
}
/* A helper for basic_lookup_transparent_type that interfaces with the
const struct block *block;
struct symbol *sym;
- if (!objfile->sf)
- return NULL;
- cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name,
- STRUCT_DOMAIN);
+ cust = objfile->lookup_symbol (block_index, name, STRUCT_DOMAIN);
if (cust == NULL)
return NULL;
- bv = COMPUNIT_BLOCKVECTOR (cust);
+ bv = cust->blockvector ();
block = BLOCKVECTOR_BLOCK (bv, block_index);
sym = block_find_symbol (block, name, STRUCT_DOMAIN,
block_find_non_opaque_type, NULL);
if (sym == NULL)
error_in_psymtab_expansion (block_index, name, cust);
- gdb_assert (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)));
- return SYMBOL_TYPE (sym);
+ gdb_assert (!TYPE_IS_OPAQUE (sym->type ()));
+ return sym->type ();
}
/* Subroutine of basic_lookup_transparent_type to simplify it.
for (compunit_symtab *cust : objfile->compunits ())
{
- bv = COMPUNIT_BLOCKVECTOR (cust);
+ bv = cust->blockvector ();
block = BLOCKVECTOR_BLOCK (bv, block_index);
sym = block_find_symbol (block, name, STRUCT_DOMAIN,
block_find_non_opaque_type, NULL);
if (sym != NULL)
{
- gdb_assert (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)));
- return SYMBOL_TYPE (sym);
+ gdb_assert (!TYPE_IS_OPAQUE (sym->type ()));
+ return sym->type ();
}
}
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
{
- if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain))
+ if (symbol_matches_domain (sym->language (), sym->domain (), domain))
{
struct block_symbol block_sym = {sym, block};
find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
{
struct compunit_symtab *best_cust = NULL;
- CORE_ADDR distance = 0;
+ CORE_ADDR best_cust_range = 0;
struct bound_minimal_symbol msymbol;
/* If we know that this is not a text address, return failure. This is
{
for (compunit_symtab *cust : obj_file->compunits ())
{
- const struct block *b;
- const struct blockvector *bv;
+ const struct blockvector *bv = cust->blockvector ();
+ const struct block *global_block
+ = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ CORE_ADDR start = BLOCK_START (global_block);
+ CORE_ADDR end = BLOCK_END (global_block);
+ bool in_range_p = start <= pc && pc < end;
+ if (!in_range_p)
+ continue;
+
+ if (BLOCKVECTOR_MAP (bv))
+ {
+ if (addrmap_find (BLOCKVECTOR_MAP (bv), pc) == nullptr)
+ continue;
+
+ return cust;
+ }
- bv = COMPUNIT_BLOCKVECTOR (cust);
- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ CORE_ADDR range = end - start;
+ if (best_cust != nullptr
+ && range >= best_cust_range)
+ /* Cust doesn't have a smaller range than best_cust, skip it. */
+ continue;
+
+ /* For an objfile that has its functions reordered,
+ find_pc_psymtab will find the proper partial symbol table
+ and we simply return its corresponding symtab. */
+ /* In order to better support objfiles that contain both
+ stabs and coff debugging info, we continue on if a psymtab
+ can't be found. */
+ if ((obj_file->flags & OBJF_REORDERED) != 0)
+ {
+ struct compunit_symtab *result;
+
+ result
+ = obj_file->find_pc_sect_compunit_symtab (msymbol,
+ pc,
+ section,
+ 0);
+ if (result != NULL)
+ return result;
+ }
- if (BLOCK_START (b) <= pc
- && BLOCK_END (b) > pc
- && (distance == 0
- || BLOCK_END (b) - BLOCK_START (b) < distance))
+ if (section != 0)
{
- /* For an objfile that has its functions reordered,
- find_pc_psymtab will find the proper partial symbol table
- and we simply return its corresponding symtab. */
- /* In order to better support objfiles that contain both
- stabs and coff debugging info, we continue on if a psymtab
- can't be found. */
- if ((obj_file->flags & OBJF_REORDERED) && obj_file->sf)
- {
- struct compunit_symtab *result;
-
- result
- = obj_file->sf->qf->find_pc_sect_compunit_symtab (obj_file,
- msymbol,
- pc,
- section,
- 0);
- if (result != NULL)
- return result;
- }
- if (section != 0)
- {
- struct block_iterator iter;
- struct symbol *sym = NULL;
+ struct symbol *sym = NULL;
+ struct block_iterator iter;
+ for (int b_index = GLOBAL_BLOCK;
+ b_index <= STATIC_BLOCK && sym == NULL;
+ ++b_index)
+ {
+ const struct block *b = BLOCKVECTOR_BLOCK (bv, b_index);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
fixup_symbol_section (sym, obj_file);
- if (matching_obj_sections (SYMBOL_OBJ_SECTION (obj_file,
- sym),
+ if (matching_obj_sections (sym->obj_section (obj_file),
section))
break;
}
- if (sym == NULL)
- continue; /* No symbol in this symtab matches
- section. */
}
- distance = BLOCK_END (b) - BLOCK_START (b);
- best_cust = cust;
+ if (sym == NULL)
+ continue; /* No symbol in this symtab matches
+ section. */
}
+
+ /* Cust is best found sofar, save it. */
+ best_cust = cust;
+ best_cust_range = range;
}
}
for (objfile *objf : current_program_space->objfiles ())
{
- struct compunit_symtab *result;
-
- if (!objf->sf)
- continue;
- result = objf->sf->qf->find_pc_sect_compunit_symtab (objf,
- msymbol,
- pc, section,
- 1);
+ struct compunit_symtab *result
+ = objf->find_pc_sect_compunit_symtab (msymbol, pc, section, 1);
if (result != NULL)
return result;
}
struct symbol *
find_symbol_at_address (CORE_ADDR address)
{
- for (objfile *objfile : current_program_space->objfiles ())
+ /* A helper function to search a given symtab for a symbol matching
+ ADDR. */
+ auto search_symtab = [] (compunit_symtab *symtab, CORE_ADDR addr) -> symbol *
{
- if (objfile->sf == NULL
- || objfile->sf->qf->find_compunit_symtab_by_address == NULL)
- continue;
+ const struct blockvector *bv = symtab->blockvector ();
- struct compunit_symtab *symtab
- = objfile->sf->qf->find_compunit_symtab_by_address (objfile, address);
- if (symtab != NULL)
+ for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
{
- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab);
+ const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
+ struct block_iterator iter;
+ struct symbol *sym;
- for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
{
- const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
- struct block_iterator iter;
- struct symbol *sym;
+ if (sym->aclass () == LOC_STATIC
+ && SYMBOL_VALUE_ADDRESS (sym) == addr)
+ return sym;
+ }
+ }
+ return nullptr;
+ };
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- if (SYMBOL_CLASS (sym) == LOC_STATIC
- && SYMBOL_VALUE_ADDRESS (sym) == address)
- return sym;
- }
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ /* If this objfile was read with -readnow, then we need to
+ search the symtabs directly. */
+ if ((objfile->flags & OBJF_READNOW) != 0)
+ {
+ for (compunit_symtab *symtab : objfile->compunits ())
+ {
+ struct symbol *sym = search_symtab (symtab, address);
+ if (sym != nullptr)
+ return sym;
+ }
+ }
+ else
+ {
+ struct compunit_symtab *symtab
+ = objfile->find_compunit_symtab_by_address (address);
+ if (symtab != NULL)
+ {
+ struct symbol *sym = search_symtab (symtab, address);
+ if (sym != nullptr)
+ return sym;
}
}
}
fatally. */
if (BMSYMBOL_VALUE_ADDRESS (mfunsym) == pc)
internal_error (__FILE__, __LINE__,
- _("Infinite recursion detected in find_pc_sect_line;"
+ _("Infinite recursion detected in find_pc_sect_line;"
"please file a bug report"));
return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
return val;
}
- bv = COMPUNIT_BLOCKVECTOR (cust);
+ bv = cust->blockvector ();
/* Look at all the symtabs that share this blockvector.
They all have the same apriori range, that we found was right;
but they have different line tables. */
- for (symtab *iter_s : compunit_filetabs (cust))
+ for (symtab *iter_s : cust->filetabs ())
{
/* Find the best line in this symtab. */
- l = SYMTAB_LINETABLE (iter_s);
+ l = iter_s->linetable ();
if (!l)
continue;
len = l->nitems;
item = l->item; /* Get first line info. */
/* Is this file's first line closer than the first lines of other files?
- If so, record this file, and its first line, as best alternate. */
+ If so, record this file, and its first line, as best alternate. */
if (item->pc > pc && (!alt || item->pc < alt->pc))
alt = item;
struct linetable_entry *last = item + len;
item = std::upper_bound (first, last, pc, pc_compare);
if (item != first)
- {
- /* Found a matching item. Skip backwards over any end of
- sequence markers. */
- for (prev = item - 1; prev->line == 0 && prev != first; prev--)
- /* Nothing. */;
- }
+ 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
- (pc >= start of the last line), then prev == item. If pc < start of
- the first line, prev will not be set. */
+ item points at the next line. If we ran off the end of the linetable
+ (pc >= start of the last line), then prev == item. If pc < start of
+ the first line, prev will not be set. */
/* Is this file's best line closer than the best in the other files?
- If so, record this file, and its best line, as best so far. Don't
- save prev if it represents the end of a function (i.e. line number
- 0) instead of a real line. */
+ If so, record this file, and its best line, as best so far. Don't
+ save prev if it represents the end of a function (i.e. line number
+ 0) instead of a real line. */
if (prev && prev->line && (!best || prev->pc > best->pc))
{
struct obj_section *section;
section = find_pc_overlay (pc);
- if (pc_in_unmapped_range (pc, section))
- pc = overlay_mapped_address (pc, section);
- return find_pc_sect_line (pc, section, notcurrent);
+ if (!pc_in_unmapped_range (pc, section))
+ return find_pc_sect_line (pc, section, notcurrent);
+
+ /* If the original PC was an unmapped address then we translate this to a
+ mapped address in order to lookup the sal. However, as the user
+ passed us an unmapped address it makes more sense to return a result
+ that has the pc and end fields translated to unmapped addresses. */
+ pc = overlay_mapped_address (pc, section);
+ symtab_and_line sal = find_pc_sect_line (pc, section, notcurrent);
+ sal.pc = overlay_unmapped_address (sal.pc, section);
+ sal.end = overlay_unmapped_address (sal.end, section);
+ return sal;
}
/* See symtab.h. */
struct symtab *best_symtab;
/* First try looking it up in the given symtab. */
- best_linetable = SYMTAB_LINETABLE (sym_tab);
+ best_linetable = sym_tab->linetable ();
best_symtab = sym_tab;
best_index = find_line_common (best_linetable, line, &exact, 0);
if (best_index < 0 || !exact)
{
/* Didn't find an exact match. So we better keep looking for
- another symtab with the same name. In the case of xcoff,
- multiple csects for one source file (produced by IBM's FORTRAN
- compiler) produce multiple symtabs (this is unavoidable
- assuming csects can be at arbitrary places in memory and that
- the GLOBAL_BLOCK of a symtab has a begin and end address). */
+ another symtab with the same name. In the case of xcoff,
+ multiple csects for one source file (produced by IBM's FORTRAN
+ compiler) produce multiple symtabs (this is unavoidable
+ assuming csects can be at arbitrary places in memory and that
+ the GLOBAL_BLOCK of a symtab has a begin and end address). */
/* BEST is the smallest linenumber > LINE so far seen,
- or 0 if none has been seen so far.
- BEST_INDEX and BEST_LINETABLE identify the item for it. */
+ or 0 if none has been seen so far.
+ BEST_INDEX and BEST_LINETABLE identify the item for it. */
int best;
if (best_index >= 0)
best = 0;
for (objfile *objfile : current_program_space->objfiles ())
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_with_fullname
- (objfile, symtab_to_fullname (sym_tab));
- }
+ objfile->expand_symtabs_with_fullname (symtab_to_fullname (sym_tab));
for (objfile *objfile : current_program_space->objfiles ())
{
for (compunit_symtab *cu : objfile->compunits ())
{
- for (symtab *s : compunit_filetabs (cu))
+ for (symtab *s : cu->filetabs ())
{
struct linetable *l;
int ind;
if (FILENAME_CMP (symtab_to_fullname (sym_tab),
symtab_to_fullname (s)) != 0)
continue;
- l = SYMTAB_LINETABLE (s);
+ l = s->linetable ();
ind = find_line_common (l, line, &exact, 0);
if (ind >= 0)
{
int was_exact;
int idx;
- idx = find_line_common (SYMTAB_LINETABLE (symtab), line, &was_exact,
+ idx = find_line_common (symtab->linetable (), line, &was_exact,
start);
if (idx < 0)
break;
if (!was_exact)
{
- struct linetable_entry *item = &SYMTAB_LINETABLE (symtab)->item[idx];
+ struct linetable_entry *item = &symtab->linetable ()->item[idx];
if (*best_item == NULL
|| (item->line < (*best_item)->line && item->is_stmt))
break;
}
- result.push_back (SYMTAB_LINETABLE (symtab)->item[idx].pc);
+ result.push_back (symtab->linetable ()->item[idx].pc);
start = idx + 1;
}
symtab = find_line_symtab (symtab, line, &ind, NULL);
if (symtab != NULL)
{
- l = SYMTAB_LINETABLE (symtab);
+ l = symtab->linetable ();
*pc = l->item[ind].pc;
return true;
}
symtab_and_line sal = find_pc_sect_line (func_addr, section, 0);
if (funfirstline && sal.symtab != NULL
- && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
- || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
+ && (sal.symtab->compunit ()->locations_valid ()
+ || sal.symtab->language () == language_asm))
{
- struct gdbarch *gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
+ struct gdbarch *gdbarch = sal.symtab->objfile ()->arch ();
sal.pc = func_addr;
if (gdbarch_skip_entrypoint_p (gdbarch))
fixup_symbol_section (sym, NULL);
symtab_and_line sal
= find_function_start_sal_1 (BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)),
- SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym),
+ sym->obj_section (symbol_objfile (sym)),
funfirstline);
sal.symbol = sym;
return sal;
int i;
/* Give up if this symbol has no lineinfo table. */
- l = SYMTAB_LINETABLE (symtab);
+ l = symtab->linetable ();
if (l == NULL)
return func_addr;
is likely to be the wrong choice. */
if (sal->symtab != nullptr
&& sal->explicit_line
- && SYMTAB_LANGUAGE (sal->symtab) == language_asm)
+ && sal->symtab->language () == language_asm)
return;
scoped_restore_current_pspace_and_thread restore_pspace_thread;
objfile = symbol_objfile (sym);
pc = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym));
- section = SYMBOL_OBJ_SECTION (objfile, sym);
+ section = sym->obj_section (objfile);
name = sym->linkage_name ();
}
else
{
struct bound_minimal_symbol msymbol
- = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
+ = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
if (msymbol.minsym == NULL)
return;
objfile = msymbol.objfile;
pc = BMSYMBOL_VALUE_ADDRESS (msymbol);
- section = MSYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
+ section = msymbol.minsym->obj_section (objfile);
name = msymbol.minsym->linkage_name ();
}
have proven the CU (Compilation Unit) supports it. sal->SYMTAB does not
have to be set by the caller so we use SYM instead. */
if (sym != NULL
- && COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (symbol_symtab (sym))))
+ && symbol_symtab (sym)->compunit ()->locations_valid ())
force_skip = 0;
saved_pc = pc;
/* Skip "first line" of function (which is actually its prologue). */
pc += gdbarch_deprecated_function_start_offset (gdbarch);
if (gdbarch_skip_entrypoint_p (gdbarch))
- pc = gdbarch_skip_entrypoint (gdbarch, pc);
+ pc = gdbarch_skip_entrypoint (gdbarch, pc);
if (skip)
pc = gdbarch_skip_prologue_noexcept (gdbarch, pc);
b = BLOCK_SUPERBLOCK (b);
}
if (function_block != NULL
- && SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0)
+ && BLOCK_FUNCTION (function_block)->line () != 0)
{
- sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block));
+ sal->line = BLOCK_FUNCTION (function_block)->line ();
sal->symtab = symbol_symtab (BLOCK_FUNCTION (function_block));
}
}
The GNU assembler emits separate line notes for each instruction
in a multi-instruction macro, but compilers generally will not
do this. */
- if (prologue_sal.symtab->language != language_asm)
+ if (prologue_sal.symtab->language () != language_asm)
{
- struct linetable *linetable = SYMTAB_LINETABLE (prologue_sal.symtab);
+ struct linetable *linetable = prologue_sal.symtab->linetable ();
int idx = 0;
/* Skip any earlier lines, and any end-of-sequence marker
symbol *sym = find_pc_function (func_addr);
if (sym != NULL
- && SYMBOL_CLASS (sym) == LOC_BLOCK
+ && sym->aclass () == LOC_BLOCK
&& BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) == func_addr)
return sym;
}
\f
-/* What part to match in a file name. */
+/* See class declaration. */
-struct filename_partial_match_opts
+info_sources_filter::info_sources_filter (match_on match_type,
+ const char *regexp)
+ : m_match_type (match_type),
+ m_regexp (regexp)
{
- /* Only match the directory name part. */
- bool dirname = false;
+ /* Setup the compiled regular expression M_C_REGEXP based on M_REGEXP. */
+ if (m_regexp != nullptr && *m_regexp != '\0')
+ {
+ gdb_assert (m_regexp != nullptr);
- /* Only match the basename part. */
- bool basename = false;
-};
+ int cflags = REG_NOSUB;
+#ifdef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
+ cflags |= REG_ICASE;
+#endif
+ m_c_regexp.emplace (m_regexp, cflags, _("Invalid regexp"));
+ }
+}
-/* Data structure to maintain printing state for output_source_filename. */
+/* See class declaration. */
+
+bool
+info_sources_filter::matches (const char *fullname) const
+{
+ /* Does it match regexp? */
+ if (m_c_regexp.has_value ())
+ {
+ const char *to_match;
+ std::string dirname;
+
+ switch (m_match_type)
+ {
+ case match_on::DIRNAME:
+ dirname = ldirname (fullname);
+ to_match = dirname.c_str ();
+ break;
+ case match_on::BASENAME:
+ to_match = lbasename (fullname);
+ break;
+ case match_on::FULLNAME:
+ to_match = fullname;
+ break;
+ default:
+ gdb_assert_not_reached ("bad m_match_type");
+ }
+
+ if (m_c_regexp->exec (to_match, 0, NULL, 0) != 0)
+ return false;
+ }
+
+ return true;
+}
+
+/* Data structure to maintain the state used for printing the results of
+ the 'info sources' command. */
struct output_source_filename_data
{
- /* Output only filenames matching REGEXP. */
- std::string regexp;
- gdb::optional<compiled_regex> c_regexp;
- /* Possibly only match a part of the filename. */
- filename_partial_match_opts partial_match;
+ /* Create an object for displaying the results of the 'info sources'
+ command to UIOUT. FILTER must remain valid and unchanged for the
+ lifetime of this object as this object retains a reference to FILTER. */
+ output_source_filename_data (struct ui_out *uiout,
+ const info_sources_filter &filter)
+ : m_filter (filter),
+ m_uiout (uiout)
+ { /* Nothing. */ }
+ DISABLE_COPY_AND_ASSIGN (output_source_filename_data);
- /* Cache of what we've seen so far. */
- struct filename_seen_cache *filename_seen_cache;
+ /* Reset enough state of this object so we can match against a new set of
+ files. The existing regular expression is retained though. */
+ void reset_output ()
+ {
+ m_first = true;
+ m_filename_seen_cache.clear ();
+ }
+
+ /* Worker for sources_info, outputs the file name formatted for either
+ cli or mi (based on the current_uiout). In cli mode displays
+ FULLNAME with a comma separating this name from any previously
+ printed name (line breaks are added at the comma). In MI mode
+ outputs a tuple containing DISP_NAME (the files display name),
+ FULLNAME, and EXPANDED_P (true when this file is from a fully
+ expanded symtab, otherwise false). */
+ void output (const char *disp_name, const char *fullname, bool expanded_p);
+
+ /* An overload suitable for use as a callback to
+ quick_symbol_functions::map_symbol_filenames. */
+ void operator() (const char *filename, const char *fullname)
+ {
+ /* The false here indicates that this file is from an unexpanded
+ symtab. */
+ output (filename, fullname, false);
+ }
+
+ /* Return true if at least one filename has been printed (after a call to
+ output) since either this object was created, or the last call to
+ reset_output. */
+ bool printed_filename_p () const
+ {
+ return !m_first;
+ }
+
+private:
/* Flag of whether we're printing the first one. */
- int first;
+ bool m_first = true;
+
+ /* Cache of what we've seen so far. */
+ filename_seen_cache m_filename_seen_cache;
+
+ /* How source filename should be filtered. */
+ const info_sources_filter &m_filter;
+
+ /* The object to which output is sent. */
+ struct ui_out *m_uiout;
};
-/* Slave routine for sources_info. Force line breaks at ,'s.
- NAME is the name to print.
- DATA contains the state for printing and watching for duplicates. */
+/* See comment in class declaration above. */
-static void
-output_source_filename (const char *name,
- struct output_source_filename_data *data)
+void
+output_source_filename_data::output (const char *disp_name,
+ const char *fullname,
+ bool expanded_p)
{
/* Since a single source file can result in several partial symbol
tables, we need to avoid printing it more than once. Note: if
situation. I'm not sure whether this can also happen for
symtabs; it doesn't hurt to check. */
- /* Was NAME already seen? */
- if (data->filename_seen_cache->seen (name))
- {
- /* Yes; don't print it again. */
- return;
- }
-
- /* Does it match data->regexp? */
- if (data->c_regexp.has_value ())
- {
- const char *to_match;
- std::string dirname;
+ /* Was NAME already seen? If so, then don't print it again. */
+ if (m_filename_seen_cache.seen (fullname))
+ return;
- if (data->partial_match.dirname)
- {
- dirname = ldirname (name);
- to_match = dirname.c_str ();
- }
- else if (data->partial_match.basename)
- to_match = lbasename (name);
- else
- to_match = name;
+ /* If the filter rejects this file then don't print it. */
+ if (!m_filter.matches (fullname))
+ return;
- if (data->c_regexp->exec (to_match, 0, NULL, 0) != 0)
- return;
- }
+ ui_out_emit_tuple ui_emitter (m_uiout, nullptr);
/* Print it and reset *FIRST. */
- if (! data->first)
- printf_filtered (", ");
- data->first = 0;
+ if (!m_first)
+ m_uiout->text (", ");
+ m_first = false;
- wrap_here ("");
- fputs_styled (name, file_name_style.style (), gdb_stdout);
+ m_uiout->wrap_hint (0);
+ if (m_uiout->is_mi_like_p ())
+ {
+ m_uiout->field_string ("file", disp_name, file_name_style.style ());
+ if (fullname != nullptr)
+ m_uiout->field_string ("fullname", fullname,
+ file_name_style.style ());
+ m_uiout->field_string ("debug-fully-read",
+ (expanded_p ? "true" : "false"));
+ }
+ else
+ {
+ if (fullname == nullptr)
+ fullname = disp_name;
+ m_uiout->field_string ("fullname", fullname,
+ file_name_style.style ());
+ }
}
-/* A callback for map_partial_symbol_filenames. */
+/* For the 'info sources' command, what part of the file names should we be
+ matching the user supplied regular expression against? */
-static void
-output_partial_symbol_filename (const char *filename, const char *fullname,
- void *data)
+struct filename_partial_match_opts
{
- output_source_filename (fullname ? fullname : filename,
- (struct output_source_filename_data *) data);
-}
+ /* Only match the directory name part. */
+ bool dirname = false;
+
+ /* Only match the basename part. */
+ bool basename = false;
+};
using isrc_flag_option_def
= gdb::option::flag_option_def<filename_partial_match_opts>;
return {{info_sources_option_defs}, isrc_opts};
}
-/* Prints the header message for the source files that will be printed
- with the matching info present in DATA. SYMBOL_MSG is a message
- that tells what will or has been done with the symbols of the
- matching source files. */
-
-static void
-print_info_sources_header (const char *symbol_msg,
- const struct output_source_filename_data *data)
-{
- puts_filtered (symbol_msg);
- if (!data->regexp.empty ())
- {
- if (data->partial_match.dirname)
- printf_filtered (_("(dirname matching regular expression \"%s\")"),
- data->regexp.c_str ());
- else if (data->partial_match.basename)
- printf_filtered (_("(basename matching regular expression \"%s\")"),
- data->regexp.c_str ());
- else
- printf_filtered (_("(filename matching regular expression \"%s\")"),
- data->regexp.c_str ());
- }
- puts_filtered ("\n");
-}
-
/* Completer for "info sources". */
static void
return;
}
-static void
-info_sources_command (const char *args, int from_tty)
-{
- struct output_source_filename_data data;
-
- if (!have_full_symbols () && !have_partial_symbols ())
- {
- error (_("No symbol table is loaded. Use the \"file\" command."));
- }
-
- filename_seen_cache filenames_seen;
-
- auto group = make_info_sources_options_def_group (&data.partial_match);
-
- gdb::option::process_options
- (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
-
- if (args != NULL && *args != '\000')
- data.regexp = args;
-
- data.filename_seen_cache = &filenames_seen;
- data.first = 1;
+/* See symtab.h. */
- if (data.partial_match.dirname && data.partial_match.basename)
- error (_("You cannot give both -basename and -dirname to 'info sources'."));
- if ((data.partial_match.dirname || data.partial_match.basename)
- && data.regexp.empty ())
- error (_("Missing REGEXP for 'info sources'."));
+void
+info_sources_worker (struct ui_out *uiout,
+ bool group_by_objfile,
+ const info_sources_filter &filter)
+{
+ output_source_filename_data data (uiout, filter);
- if (data.regexp.empty ())
- data.c_regexp.reset ();
- else
- {
- int cflags = REG_NOSUB;
-#ifdef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
- cflags |= REG_ICASE;
-#endif
- data.c_regexp.emplace (data.regexp.c_str (), cflags,
- _("Invalid regexp"));
- }
+ ui_out_emit_list results_emitter (uiout, "files");
+ gdb::optional<ui_out_emit_tuple> output_tuple;
+ gdb::optional<ui_out_emit_list> sources_list;
- print_info_sources_header
- (_("Source files for which symbols have been read in:\n"), &data);
+ gdb_assert (group_by_objfile || uiout->is_mi_like_p ());
for (objfile *objfile : current_program_space->objfiles ())
{
+ if (group_by_objfile)
+ {
+ output_tuple.emplace (uiout, nullptr);
+ uiout->field_string ("filename", objfile_name (objfile));
+ uiout->text (":\n");
+ bool debug_fully_readin = !objfile->has_unexpanded_symtabs ();
+ if (uiout->is_mi_like_p ())
+ {
+ const char *debug_info_state;
+ if (objfile_has_symbols (objfile))
+ {
+ if (debug_fully_readin)
+ debug_info_state = "fully-read";
+ else
+ debug_info_state = "partially-read";
+ }
+ else
+ debug_info_state = "none";
+ current_uiout->field_string ("debug-info", debug_info_state);
+ }
+ else
+ {
+ if (!debug_fully_readin)
+ uiout->text ("(Full debug information has not yet been read "
+ "for this file.)\n");
+ if (!objfile_has_symbols (objfile))
+ uiout->text ("(Objfile has no debug information.)\n");
+ uiout->text ("\n");
+ }
+ sources_list.emplace (uiout, "sources");
+ }
+
for (compunit_symtab *cu : objfile->compunits ())
{
- for (symtab *s : compunit_filetabs (cu))
+ for (symtab *s : cu->filetabs ())
{
+ const char *file = symtab_to_filename_for_display (s);
const char *fullname = symtab_to_fullname (s);
-
- output_source_filename (fullname, &data);
+ data.output (file, fullname, true);
}
}
+
+ if (group_by_objfile)
+ {
+ objfile->map_symbol_filenames (data, true /* need_fullname */);
+ if (data.printed_filename_p ())
+ uiout->text ("\n\n");
+ data.reset_output ();
+ sources_list.reset ();
+ output_tuple.reset ();
+ }
+ }
+
+ if (!group_by_objfile)
+ {
+ data.reset_output ();
+ map_symbol_filenames (data, true /*need_fullname*/);
}
- printf_filtered ("\n\n");
+}
- print_info_sources_header
- (_("Source files for which symbols will be read in on demand:\n"), &data);
+/* Implement the 'info sources' command. */
- filenames_seen.clear ();
- data.first = 1;
- map_symbol_filenames (output_partial_symbol_filename, &data,
- 1 /*need_fullname*/);
- printf_filtered ("\n");
+static void
+info_sources_command (const char *args, int from_tty)
+{
+ if (!have_full_symbols () && !have_partial_symbols ())
+ error (_("No symbol table is loaded. Use the \"file\" command."));
+
+ filename_partial_match_opts match_opts;
+ auto group = make_info_sources_options_def_group (&match_opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
+
+ if (match_opts.dirname && match_opts.basename)
+ error (_("You cannot give both -basename and -dirname to 'info sources'."));
+
+ const char *regex = nullptr;
+ if (args != NULL && *args != '\000')
+ regex = args;
+
+ if ((match_opts.dirname || match_opts.basename) && regex == nullptr)
+ error (_("Missing REGEXP for 'info sources'."));
+
+ info_sources_filter::match_on match_type;
+ if (match_opts.dirname)
+ match_type = info_sources_filter::match_on::DIRNAME;
+ else if (match_opts.basename)
+ match_type = info_sources_filter::match_on::BASENAME;
+ else
+ match_type = info_sources_filter::match_on::FULLNAME;
+
+ info_sources_filter filter (match_type, regex);
+ info_sources_worker (current_uiout, true, filter);
}
/* Compare FILE against all the entries of FILENAMES. If BASENAMES is
sym->natural_name ());
}
- sym_type = SYMBOL_TYPE (sym);
+ sym_type = sym->type ();
if (sym_type == NULL)
return false;
enum search_domain kind = m_kind;
bool found_msymbol = false;
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching
- (objfile,
- [&] (const char *filename, bool basenames)
- {
- return file_matches (filename, filenames, basenames);
- },
- &lookup_name_info::match_any (),
- [&] (const char *symname)
- {
- return (!preg.has_value ()
- || preg->exec (symname, 0, NULL, 0) == 0);
- },
- NULL,
- kind);
+ auto do_file_match = [&] (const char *filename, bool basenames)
+ {
+ return file_matches (filename, filenames, basenames);
+ };
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher = nullptr;
+ if (!filenames.empty ())
+ file_matcher = do_file_match;
+
+ objfile->expand_symtabs_matching
+ (file_matcher,
+ &lookup_name_info::match_any (),
+ [&] (const char *symname)
+ {
+ return (!preg.has_value ()
+ || preg->exec (symname, 0, NULL, 0) == 0);
+ },
+ NULL,
+ SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
+ UNDEF_DOMAIN,
+ kind);
/* Here, we search through the minimal symbol tables for functions and
variables that match, and force their symbols to be read. This is in
/* Add matching symbols (if not already present). */
for (compunit_symtab *cust : objfile->compunits ())
{
- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
+ const struct blockvector *bv = cust->blockvector ();
for (block_enum block : { GLOBAL_BLOCK, STATIC_BLOCK })
{
|| preg->exec (sym->natural_name (), 0,
NULL, 0) == 0)
&& ((kind == VARIABLES_DOMAIN
- && SYMBOL_CLASS (sym) != LOC_TYPEDEF
- && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
- && SYMBOL_CLASS (sym) != LOC_BLOCK
+ && sym->aclass () != LOC_TYPEDEF
+ && sym->aclass () != LOC_UNRESOLVED
+ && sym->aclass () != LOC_BLOCK
/* LOC_CONST can be used for more than
just enums, e.g., c++ static const
members. We only want to skip enums
here. */
- && !(SYMBOL_CLASS (sym) == LOC_CONST
- && (SYMBOL_TYPE (sym)->code ()
+ && !(sym->aclass () == LOC_CONST
+ && (sym->type ()->code ()
== TYPE_CODE_ENUM))
&& (!treg.has_value ()
|| treg_matches_sym_type_name (*treg, sym)))
|| (kind == FUNCTIONS_DOMAIN
- && SYMBOL_CLASS (sym) == LOC_BLOCK
+ && sym->aclass () == LOC_BLOCK
&& (!treg.has_value ()
|| treg_matches_sym_type_name (*treg,
sym)))
|| (kind == TYPES_DOMAIN
- && SYMBOL_CLASS (sym) == LOC_TYPEDEF
- && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN)
+ && sym->aclass () == LOC_TYPEDEF
+ && sym->domain () != MODULE_DOMAIN)
|| (kind == MODULES_DOMAIN
- && SYMBOL_DOMAIN (sym) == MODULE_DOMAIN
- && SYMBOL_LINE (sym) != 0))))
+ && sym->domain () == MODULE_DOMAIN
+ && sym->line () != 0))))
{
if (result_set->size () < m_max_search_results)
{
const char *symbol_name_regexp = m_symbol_name_regexp;
/* Make sure spacing is right for C++ operators.
- This is just a courtesy to make the matching less sensitive
- to how many spaces the user leaves between 'operator'
- and <TYPENAME> or <OPERATOR>. */
+ This is just a courtesy to make the matching less sensitive
+ to how many spaces the user leaves between 'operator'
+ and <TYPENAME> or <OPERATOR>. */
const char *opend;
const char *opname = operator_chars (symbol_name_regexp, &opend);
if (*opname)
{
int fix = -1; /* -1 means ok; otherwise number of
- spaces needed. */
+ spaces needed. */
if (isalpha (*opname) || *opname == '_' || *opname == '$')
{
/* Typedef that is not a C++ class. */
if (kind == TYPES_DOMAIN
- && SYMBOL_DOMAIN (sym) != STRUCT_DOMAIN)
+ && sym->domain () != STRUCT_DOMAIN)
{
string_file tmp_stream;
For the struct printing case below, things are worse, we force
printing of the ";" in this function, which is going to be wrong
for languages that don't require a ";" between statements. */
- if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_TYPEDEF)
- typedef_print (SYMBOL_TYPE (sym), sym, &tmp_stream);
+ if (sym->type ()->code () == TYPE_CODE_TYPEDEF)
+ typedef_print (sym->type (), sym, &tmp_stream);
else
- type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1);
+ type_print (sym->type (), "", &tmp_stream, -1);
str += tmp_stream.string ();
}
/* variable, func, or typedef-that-is-c++-class. */
else if (kind < TYPES_DOMAIN
|| (kind == TYPES_DOMAIN
- && SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN))
+ && sym->domain () == STRUCT_DOMAIN))
{
string_file tmp_stream;
- type_print (SYMBOL_TYPE (sym),
- (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+ type_print (sym->type (),
+ (sym->aclass () == LOC_TYPEDEF
? "" : sym->print_name ()),
&tmp_stream, 0);
s_filename));
}
- if (SYMBOL_LINE (sym) != 0)
- printf_filtered ("%d:\t", SYMBOL_LINE (sym));
+ if (sym->line () != 0)
+ printf_filtered ("%d:\t", sym->line ());
else
puts_filtered ("\t");
}
{
bool quiet = false;
bool exclude_minsyms = false;
- char *type_regexp = nullptr;
-
- ~info_vars_funcs_options ()
- {
- xfree (type_regexp);
- }
+ std::string type_regexp;
};
/* The options used by the 'info variables' and 'info functions'
gdb::option::string_option_def<info_vars_funcs_options> {
"t",
- [] (info_vars_funcs_options *opt) { return &opt->type_regexp;
- },
+ [] (info_vars_funcs_options *opt) { return &opt->type_regexp; },
nullptr, /* show_cmd_cb */
nullptr /* set_doc */
}
if (args != nullptr && *args == '\0')
args = nullptr;
- symtab_symbol_info (opts.quiet, opts.exclude_minsyms, args, VARIABLES_DOMAIN,
- opts.type_regexp, from_tty);
+ symtab_symbol_info
+ (opts.quiet, opts.exclude_minsyms, args, VARIABLES_DOMAIN,
+ opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
+ from_tty);
}
/* Implement the 'info functions' command. */
if (args != nullptr && *args == '\0')
args = nullptr;
- symtab_symbol_info (opts.quiet, opts.exclude_minsyms, args,
- FUNCTIONS_DOMAIN, opts.type_regexp, from_tty);
+ symtab_symbol_info
+ (opts.quiet, opts.exclude_minsyms, args, FUNCTIONS_DOMAIN,
+ opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
+ from_tty);
}
/* Holds the -q option for the 'info types' command. */
{
const char *colon = strchr (regexp, ':');
+ /* Ignore the colon if it is part of a Windows drive. */
+ if (HAS_DRIVE_SPEC (regexp)
+ && (regexp[2] == '/' || regexp[2] == '\\'))
+ colon = strchr (STRIP_DRIVE_SPEC (regexp), ':');
+
if (colon && *(colon + 1) != ':')
{
int colon_index;
const language_defn *lang = language_def (symbol_language);
symbol_name_matcher_ftype *name_match
- = get_symbol_name_matcher (lang, lookup_name);
+ = lang->get_symbol_name_matcher (lookup_name);
return name_match (symbol_name, lookup_name, &match_res);
}
/* See symtab.h. */
-void
+bool
completion_list_add_name (completion_tracker &tracker,
language symbol_language,
const char *symname,
/* Clip symbols that cannot match. */
if (!compare_symbol_name (symname, symbol_language, lookup_name, match_res))
- return;
+ return false;
/* Refresh SYMNAME from the match string. It's potentially
different depending on language. (E.g., on Ada, the match may be
tracker.add_completion (std::move (completion),
&match_res.match_for_lcd, text, word);
}
+
+ return true;
}
/* completion_list_add_name wrapper for struct symbol. */
const lookup_name_info &lookup_name,
const char *text, const char *word)
{
- completion_list_add_name (tracker, sym->language (),
- sym->natural_name (),
- lookup_name, text, word);
+ if (!completion_list_add_name (tracker, sym->language (),
+ sym->natural_name (),
+ lookup_name, text, word))
+ return;
/* C++ function symbols include the parameters within both the msymbol
name and the symbol name. The problem is that the msymbol name will
the msymbol name and removes the msymbol name from the completion
tracker. */
if (sym->language () == language_cplus
- && SYMBOL_DOMAIN (sym) == VAR_DOMAIN
- && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ && sym->domain () == VAR_DOMAIN
+ && sym->aclass () == LOC_BLOCK)
{
/* The call to canonicalize returns the empty string if the input
string is already in canonical form, thanks to this we don't
const lookup_name_info &lookup_name,
const char *text, const char *word)
{
- if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ if (sym->aclass () == LOC_TYPEDEF)
{
- struct type *t = SYMBOL_TYPE (sym);
+ struct type *t = sym->type ();
enum type_code c = t->code ();
int j;
if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
for (j = TYPE_N_BASECLASSES (t); j < t->num_fields (); j++)
- if (TYPE_FIELD_NAME (t, j))
+ if (t->field (j).name ())
completion_list_add_name (tracker, sym->language (),
- TYPE_FIELD_NAME (t, j),
+ t->field (j).name (),
lookup_name, text, word);
}
}
bool
symbol_is_function_or_method (symbol *sym)
{
- switch (SYMBOL_TYPE (sym)->code ())
+ switch (sym->type ()->code ())
{
case TYPE_CODE_FUNC:
case TYPE_CODE_METHOD:
bound_minimal_symbol
find_gnu_ifunc (const symbol *sym)
{
- if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+ if (sym->aclass () != LOC_BLOCK)
return {};
lookup_name_info lookup_name (sym->search_name (),
if (MSYMBOL_TYPE (minsym) == mst_data_gnu_ifunc)
{
struct gdbarch *gdbarch = objfile->arch ();
- msym_addr
- = gdbarch_convert_from_func_ptr_addr (gdbarch,
- msym_addr,
- current_top_target ());
+ msym_addr = gdbarch_convert_from_func_ptr_addr
+ (gdbarch, msym_addr, current_inferior ()->top_target ());
}
if (msym_addr == address)
{
for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
{
QUIT;
- b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), i);
+ b = BLOCKVECTOR_BLOCK (cust->blockvector (), i);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
if (completion_skip_symbol (mode, sym))
continue;
if (code == TYPE_CODE_UNDEF
- || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
- && SYMBOL_TYPE (sym)->code () == code))
+ || (sym->domain () == STRUCT_DOMAIN
+ && sym->type ()->code () == code))
completion_list_add_symbol (tracker, sym,
lookup_name,
text, word);
if (mode == complete_symbol_mode::LINESPEC)
sym_text = text;
else
- {
- const char *p;
- char quote_found;
- const char *quote_pos = NULL;
+ {
+ const char *p;
+ char quote_found;
+ const char *quote_pos = NULL;
- /* First see if this is a quoted string. */
- quote_found = '\0';
- for (p = text; *p != '\0'; ++p)
- {
- if (quote_found != '\0')
- {
- if (*p == quote_found)
- /* Found close quote. */
- quote_found = '\0';
- else if (*p == '\\' && p[1] == quote_found)
- /* A backslash followed by the quote character
- doesn't end the string. */
- ++p;
- }
- else if (*p == '\'' || *p == '"')
- {
- quote_found = *p;
- quote_pos = p;
- }
- }
- if (quote_found == '\'')
- /* A string within single quotes can be a symbol, so complete on it. */
- sym_text = quote_pos + 1;
- else if (quote_found == '"')
- /* A double-quoted string is never a symbol, nor does it make sense
- to complete it any other way. */
- {
- return;
- }
- else
- {
- /* It is not a quoted string. Break it based on the characters
- which are in symbols. */
- while (p > text)
- {
- if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
- || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
- --p;
- else
- break;
- }
- sym_text = p;
- }
- }
+ /* First see if this is a quoted string. */
+ quote_found = '\0';
+ for (p = text; *p != '\0'; ++p)
+ {
+ if (quote_found != '\0')
+ {
+ if (*p == quote_found)
+ /* Found close quote. */
+ quote_found = '\0';
+ else if (*p == '\\' && p[1] == quote_found)
+ /* A backslash followed by the quote character
+ doesn't end the string. */
+ ++p;
+ }
+ else if (*p == '\'' || *p == '"')
+ {
+ quote_found = *p;
+ quote_pos = p;
+ }
+ }
+ if (quote_found == '\'')
+ /* A string within single quotes can be a symbol, so complete on it. */
+ sym_text = quote_pos + 1;
+ else if (quote_found == '"')
+ /* A double-quoted string is never a symbol, nor does it make sense
+ to complete it any other way. */
+ {
+ return;
+ }
+ else
+ {
+ /* It is not a quoted string. Break it based on the characters
+ which are in symbols. */
+ while (p > text)
+ {
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
+ || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
+ --p;
+ else
+ break;
+ }
+ sym_text = p;
+ }
+ }
lookup_name_info lookup_name (sym_text, name_match_type, true);
add_symtab_completions (symtab,
tracker, mode, lookup_name,
sym_text, word, code);
+ return true;
},
+ SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
ALL_DOMAIN);
/* Search upwards from currently selected frame (so that we can
completion_list_add_fields (tracker, sym, lookup_name,
sym_text, word);
}
- else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
- && SYMBOL_TYPE (sym)->code () == code)
+ else if (sym->domain () == STRUCT_DOMAIN
+ && sym->type ()->code () == code)
completion_list_add_symbol (tracker, sym, lookup_name,
sym_text, word);
}
/* Skip macros if we are completing a struct tag -- arguable but
usually what is expected. */
- if (current_language->la_macro_expansion == macro_expansion_c
+ if (current_language->macro_expansion () == macro_expansion_c
&& code == TYPE_CODE_UNDEF)
{
gdb::unique_xmalloc_ptr<struct macro_scope> scope;
}
}
-void
-default_collect_symbol_completion_matches (completion_tracker &tracker,
- complete_symbol_mode mode,
- symbol_name_match_type name_match_type,
- const char *text, const char *word,
- enum type_code code)
-{
- return default_collect_symbol_completion_matches_break_on (tracker, mode,
- name_match_type,
- text, word, "",
- code);
-}
-
/* Collect all symbols (regardless of class) which begin by matching
TEXT. */
symbol_name_match_type name_match_type,
const char *text, const char *word)
{
- current_language->la_collect_symbol_completion_matches (tracker, mode,
- name_match_type,
- text, word,
- TYPE_CODE_UNDEF);
+ current_language->collect_symbol_completion_matches (tracker, mode,
+ name_match_type,
+ text, word,
+ TYPE_CODE_UNDEF);
}
/* Like collect_symbol_completion_matches, but only collect
gdb_assert (code == TYPE_CODE_UNION
|| code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_ENUM);
- current_language->la_collect_symbol_completion_matches (tracker, mode,
- name_match_type,
- text, word, code);
+ current_language->collect_symbol_completion_matches (tracker, mode,
+ name_match_type,
+ text, word, code);
}
/* Like collect_symbol_completion_matches, but collects a list of
if (mode == complete_symbol_mode::LINESPEC)
sym_text = text;
else
- {
- const char *p;
- char quote_found;
- const char *quote_pos = NULL;
+ {
+ const char *p;
+ char quote_found;
+ const char *quote_pos = NULL;
- /* First see if this is a quoted string. */
- quote_found = '\0';
- for (p = text; *p != '\0'; ++p)
- {
- if (quote_found != '\0')
- {
- if (*p == quote_found)
- /* Found close quote. */
- quote_found = '\0';
- else if (*p == '\\' && p[1] == quote_found)
- /* A backslash followed by the quote character
- doesn't end the string. */
- ++p;
- }
- else if (*p == '\'' || *p == '"')
- {
- quote_found = *p;
- quote_pos = p;
- }
- }
- if (quote_found == '\'')
- /* A string within single quotes can be a symbol, so complete on it. */
- sym_text = quote_pos + 1;
- else if (quote_found == '"')
- /* A double-quoted string is never a symbol, nor does it make sense
- to complete it any other way. */
- {
- return;
- }
- else
- {
- /* Not a quoted string. */
- sym_text = language_search_unquoted_string (text, p);
- }
- }
+ /* First see if this is a quoted string. */
+ quote_found = '\0';
+ for (p = text; *p != '\0'; ++p)
+ {
+ if (quote_found != '\0')
+ {
+ if (*p == quote_found)
+ /* Found close quote. */
+ quote_found = '\0';
+ else if (*p == '\\' && p[1] == quote_found)
+ /* A backslash followed by the quote character
+ doesn't end the string. */
+ ++p;
+ }
+ else if (*p == '\'' || *p == '"')
+ {
+ quote_found = *p;
+ quote_pos = p;
+ }
+ }
+ if (quote_found == '\'')
+ /* A string within single quotes can be a symbol, so complete on it. */
+ sym_text = quote_pos + 1;
+ else if (quote_found == '"')
+ /* A double-quoted string is never a symbol, nor does it make sense
+ to complete it any other way. */
+ {
+ return;
+ }
+ else
+ {
+ /* Not a quoted string. */
+ sym_text = language_search_unquoted_string (text, p);
+ }
+ }
lookup_name_info lookup_name (sym_text, name_match_type, true);
for symbols which match. */
iterate_over_symtabs (srcfile, [&] (symtab *s)
{
- add_symtab_completions (SYMTAB_COMPUNIT (s),
+ add_symtab_completions (s->compunit (),
tracker, mode, lookup_name,
sym_text, word, TYPE_CODE_UNDEF);
return false;
return 0;
}
-/* An object of this type is passed as the user_data argument to
+/* An object of this type is passed as the callback argument to
map_partial_symbol_filenames. */
struct add_partial_filename_data
{
const char *word;
int text_len;
completion_list *list;
+
+ void operator() (const char *filename, const char *fullname);
};
/* A callback for map_partial_symbol_filenames. */
-static void
-maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
- void *user_data)
+void
+add_partial_filename_data::operator() (const char *filename,
+ const char *fullname)
{
- struct add_partial_filename_data *data
- = (struct add_partial_filename_data *) user_data;
-
if (not_interesting_fname (filename))
return;
- if (!data->filename_seen_cache->seen (filename)
- && filename_ncmp (filename, data->text, data->text_len) == 0)
+ if (!filename_seen_cache->seen (filename)
+ && filename_ncmp (filename, text, text_len) == 0)
{
/* This file matches for a completion; add it to the
current list of matches. */
- add_filename_to_list (filename, data->text, data->word, data->list);
+ add_filename_to_list (filename, text, word, list);
}
else
{
const char *base_name = lbasename (filename);
if (base_name != filename
- && !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);
+ && !filename_seen_cache->seen (base_name)
+ && filename_ncmp (base_name, text, text_len) == 0)
+ add_filename_to_list (base_name, text, word, list);
}
}
{
for (compunit_symtab *cu : objfile->compunits ())
{
- for (symtab *s : compunit_filetabs (cu))
+ for (symtab *s : cu->filetabs ())
{
if (not_interesting_fname (s->filename))
continue;
datum.word = word;
datum.text_len = text_len;
datum.list = &list;
- map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
- 0 /*need_fullname*/);
+ map_symbol_filenames (datum, false /*need_fullname*/);
return list;
}
"ARM/Thumb C/C++ Compiler, RVCT",
"ARM C/C++ Compiler, RVCT"
};
- int i;
if (producer == NULL)
return false;
- for (i = 0; i < ARRAY_SIZE (arm_idents); i++)
- if (startswith (producer, arm_idents[i]))
+ for (const char *ident : arm_idents)
+ if (startswith (producer, ident))
return true;
return false;
struct objfile *
symbol_objfile (const struct symbol *symbol)
{
- gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
- return SYMTAB_OBJFILE (symbol->owner.symtab);
+ gdb_assert (symbol->is_objfile_owned ());
+ return symbol->owner.symtab->objfile ();
}
/* See symtab.h. */
struct gdbarch *
symbol_arch (const struct symbol *symbol)
{
- if (!SYMBOL_OBJFILE_OWNED (symbol))
+ if (!symbol->is_objfile_owned ())
return symbol->owner.arch;
- return SYMTAB_OBJFILE (symbol->owner.symtab)->arch ();
+ return symbol->owner.symtab->objfile ()->arch ();
}
/* See symtab.h. */
struct symtab *
symbol_symtab (const struct symbol *symbol)
{
- gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ gdb_assert (symbol->is_objfile_owned ());
return symbol->owner.symtab;
}
void
symbol_set_symtab (struct symbol *symbol, struct symtab *symtab)
{
- gdb_assert (SYMBOL_OBJFILE_OWNED (symbol));
+ gdb_assert (symbol->is_objfile_owned ());
symbol->owner.symtab = symtab;
}
get_symbol_address (const struct symbol *sym)
{
gdb_assert (sym->maybe_copied);
- gdb_assert (SYMBOL_CLASS (sym) == LOC_STATIC);
+ gdb_assert (sym->aclass () == LOC_STATIC);
const char *linkage_name = sym->linkage_name ();
return BMSYMBOL_VALUE_ADDRESS (found);
}
}
- return minsym->value.address + objf->section_offsets[minsym->section];
+ return (minsym->value.address
+ + objf->section_offsets[minsym->section_index ()]);
}
\f
struct info_modules_var_func_options
{
bool quiet = false;
- char *type_regexp = nullptr;
- char *module_regexp = nullptr;
-
- ~info_modules_var_func_options ()
- {
- xfree (type_regexp);
- xfree (module_regexp);
- }
+ std::string type_regexp;
+ std::string module_regexp;
};
/* The options used by 'info module variables' and 'info module functions'
if (args != nullptr && *args == '\0')
args = nullptr;
- info_module_subcommand (opts.quiet, opts.module_regexp, args,
- opts.type_regexp, FUNCTIONS_DOMAIN);
+ info_module_subcommand
+ (opts.quiet,
+ opts.module_regexp.empty () ? nullptr : opts.module_regexp.c_str (), args,
+ opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
+ FUNCTIONS_DOMAIN);
}
/* Implements the 'info module variables' command. */
if (args != nullptr && *args == '\0')
args = nullptr;
- info_module_subcommand (opts.quiet, opts.module_regexp, args,
- opts.type_regexp, VARIABLES_DOMAIN);
+ info_module_subcommand
+ (opts.quiet,
+ opts.module_regexp.empty () ? nullptr : opts.module_regexp.c_str (), args,
+ opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
+ VARIABLES_DOMAIN);
}
/* Command completer for 'info module ...' sub-commands. */
REGEXP is given. The optional flag -q disables printing of headers."));
set_cmd_completer_handle_brkchars (c, info_types_command_completer);
- const auto info_sources_opts = make_info_sources_options_def_group (nullptr);
+ const auto info_sources_opts
+ = make_info_sources_options_def_group (nullptr);
static std::string info_sources_help
= gdb::option::build_help (_("\
add_basic_prefix_cmd ("module", class_info, _("\
Print information about modules."),
- &info_module_cmdlist, "info module ",
- 0, &infolist);
+ &info_module_cmdlist, 0, &infolist);
c = add_cmd ("functions", class_info, info_module_functions_command, _("\
Display functions arranged by modules.\n\
_("Set a breakpoint for all functions matching REGEXP."));
add_setshow_enum_cmd ("multiple-symbols", no_class,
- multiple_symbols_modes, &multiple_symbols_mode,
- _("\
+ multiple_symbols_modes, &multiple_symbols_mode,
+ _("\
Set how the debugger handles ambiguities in expressions."), _("\
Show how the debugger handles ambiguities in expressions."), _("\
Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
- NULL, NULL, &setlist, &showlist);
+ NULL, NULL, &setlist, &showlist);
add_setshow_boolean_cmd ("basenames-may-differ", class_obscure,
&basenames_may_differ, _("\
_("Print symbol cache statistics for each program space."),
&maintenanceprintlist);
- add_cmd ("flush-symbol-cache", class_maintenance,
- maintenance_flush_symbol_cache,
- _("Flush the symbol cache for each program space."),
- &maintenancelist);
-
- 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);
+ cmd_list_element *maintenance_flush_symbol_cache_cmd
+ = add_cmd ("symbol-cache", class_maintenance,
+ maintenance_flush_symbol_cache,
+ _("Flush the symbol cache for each program space."),
+ &maintenanceflushlist);
+ c = add_alias_cmd ("flush-symbol-cache", maintenance_flush_symbol_cache_cmd,
+ class_maintenance, 0, &maintenancelist);
+ deprecate_cmd (c, "maintenancelist flush symbol-cache");
+
+ gdb::observers::executable_changed.attach (symtab_observer_executable_changed,
+ "symtab");
+ gdb::observers::new_objfile.attach (symtab_new_objfile_observer, "symtab");
+ gdb::observers::free_objfile.attach (symtab_free_objfile_observer, "symtab");
}