#include "source.h"
#include "filenames.h" /* for FILENAME_CMP */
#include "objc-lang.h"
+#include "d-lang.h"
#include "ada-lang.h"
#include "p-lang.h"
#include "addrmap.h"
if (full_path != NULL)
{
const char *fp = symtab_to_fullname (s);
+
if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
{
return s;
if (real_path != NULL)
{
char *fullname = symtab_to_fullname (s);
+
if (fullname != NULL)
{
char *rp = gdb_realpath (fullname);
+
make_cleanup (xfree, rp);
if (FILENAME_CMP (real_path, rp) == 0)
{
mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
+ strlen (buf) + len + strlen (physname) + 1);
- {
- mangled_name = (char *) xmalloc (mangled_name_len);
- if (is_constructor)
- mangled_name[0] = '\0';
- else
- strcpy (mangled_name, field_name);
- }
+ mangled_name = (char *) xmalloc (mangled_name_len);
+ if (is_constructor)
+ mangled_name[0] = '\0';
+ else
+ strcpy (mangled_name, field_name);
+
strcat (mangled_name, buf);
/* If the class doesn't have a name, i.e. newname NULL, then we just
mangle it using 0 for the length of the class. Thus it gets mangled
return (mangled_name);
}
+/* Initialize the cplus_specific structure. 'cplus_specific' should
+ only be allocated for use with cplus symbols. */
+
+static void
+symbol_init_cplus_specific (struct general_symbol_info *gsymbol,
+ struct objfile *objfile)
+{
+ /* A language_specific structure should not have been previously
+ initialized. */
+ gdb_assert (gsymbol->language_specific.cplus_specific == NULL);
+ gdb_assert (objfile != NULL);
+
+ gsymbol->language_specific.cplus_specific =
+ OBSTACK_ZALLOC (&objfile->objfile_obstack, struct cplus_specific);
+}
+
+/* Set the demangled name of GSYMBOL to NAME. NAME must be already
+ correctly allocated. For C++ symbols a cplus_specific struct is
+ allocated so OBJFILE must not be NULL. If this is a non C++ symbol
+ OBJFILE can be NULL. */
+void
+symbol_set_demangled_name (struct general_symbol_info *gsymbol,
+ char *name,
+ struct objfile *objfile)
+{
+ if (gsymbol->language == language_cplus)
+ {
+ if (gsymbol->language_specific.cplus_specific == NULL)
+ symbol_init_cplus_specific (gsymbol, objfile);
+
+ gsymbol->language_specific.cplus_specific->demangled_name = name;
+ }
+ else
+ gsymbol->language_specific.mangled_lang.demangled_name = name;
+}
+
+/* Return the demangled name of GSYMBOL. */
+char *
+symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language == language_cplus)
+ {
+ gdb_assert (gsymbol->language_specific.cplus_specific != NULL);
+ return gsymbol->language_specific.cplus_specific->demangled_name;
+ }
+ else
+ return gsymbol->language_specific.mangled_lang.demangled_name;
+}
+
\f
/* Initialize the language dependent portion of a symbol
depending upon the language for the symbol. */
symbol_init_language_specific (struct general_symbol_info *gsymbol,
enum language language)
{
+
gsymbol->language = language;
if (gsymbol->language == language_cplus
+ || gsymbol->language == language_d
|| gsymbol->language == language_java
- || gsymbol->language == language_objc)
+ || gsymbol->language == language_objc
+ || gsymbol->language == language_fortran)
{
- gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ symbol_set_demangled_name (gsymbol, NULL, NULL);
}
+ else if (gsymbol->language == language_cplus)
+ gsymbol->language_specific.cplus_specific = NULL;
else
{
memset (&gsymbol->language_specific, 0,
hash_demangled_name_entry (const void *data)
{
const struct demangled_name_entry *e = data;
+
return htab_hash_string (e->mangled);
}
{
const struct demangled_name_entry *da = a;
const struct demangled_name_entry *db = b;
+
return strcmp (da->mangled, db->mangled) == 0;
}
return demangled;
}
}
+ if (gsymbol->language == language_d
+ || gsymbol->language == language_auto)
+ {
+ demangled = d_demangle(mangled, 0);
+ if (demangled != NULL)
+ {
+ gsymbol->language = language_d;
+ return demangled;
+ }
+ }
+ /* We could support `gsymbol->language == language_fortran' here to provide
+ module namespaces also for inferiors with only minimal symbol table (ELF
+ symbols). Just the mangling standard is not standardized across compilers
+ and there is no DW_AT_producer available for inferiors with only the ELF
+ symbols to check the mangling kind. */
return NULL;
}
memcpy (gsymbol->name, linkage_name, len);
gsymbol->name[len] = '\0';
}
- gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ symbol_set_demangled_name (gsymbol, NULL, NULL);
return;
}
if (gsymbol->language == language_java)
{
char *alloc_name;
- lookup_len = len + JAVA_PREFIX_LEN;
+ lookup_len = len + JAVA_PREFIX_LEN;
alloc_name = alloca (lookup_len + 1);
memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN);
memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len);
else if (linkage_name[len] != '\0')
{
char *alloc_name;
- lookup_len = len;
+ lookup_len = len;
alloc_name = alloca (lookup_len + 1);
memcpy (alloc_name, linkage_name, len);
alloc_name[lookup_len] = '\0';
It turns out that it is actually important to still save such
an entry in the hash table, because storing this name gives
- us better backache hit rates for partial symbols. */
+ us better bcache hit rates for partial symbols. */
if (!copy_name && lookup_name == linkage_name)
{
*slot = obstack_alloc (&objfile->objfile_obstack,
gsymbol->name = (*slot)->mangled + lookup_len - len;
if ((*slot)->demangled[0] != '\0')
- gsymbol->language_specific.cplus_specific.demangled_name
- = (*slot)->demangled;
+ symbol_set_demangled_name (gsymbol, (*slot)->demangled, objfile);
else
- gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ symbol_set_demangled_name (gsymbol, NULL, objfile);
}
/* Return the source code name of a symbol. In languages where
switch (gsymbol->language)
{
case language_cplus:
+ case language_d:
case language_java:
case language_objc:
- if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
- return gsymbol->language_specific.cplus_specific.demangled_name;
+ case language_fortran:
+ if (symbol_get_demangled_name (gsymbol) != NULL)
+ return symbol_get_demangled_name (gsymbol);
break;
case language_ada:
- if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
- return gsymbol->language_specific.cplus_specific.demangled_name;
+ if (symbol_get_demangled_name (gsymbol) != NULL)
+ return symbol_get_demangled_name (gsymbol);
else
return ada_decode_symbol (gsymbol);
break;
switch (gsymbol->language)
{
case language_cplus:
+ case language_d:
case language_java:
case language_objc:
- if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
- return gsymbol->language_specific.cplus_specific.demangled_name;
+ case language_fortran:
+ if (symbol_get_demangled_name (gsymbol) != NULL)
+ return symbol_get_demangled_name (gsymbol);
break;
case language_ada:
- if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
- return gsymbol->language_specific.cplus_specific.demangled_name;
+ if (symbol_get_demangled_name (gsymbol) != NULL)
+ return symbol_get_demangled_name (gsymbol);
else
return ada_decode_symbol (gsymbol);
break;
ALL_OBJFILES (objfile)
{
struct symtab *result = NULL;
+
if (objfile->sf)
result = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol,
pc, section, 0);
a search of the section table. */
struct obj_section *s;
+
ALL_OBJFILE_OSECTIONS (objfile, s)
{
int idx = s->the_bfd_section->index;
modified_name = name;
- /* If we are using C++ or Java, demangle the name before doing a lookup, so
- we can always binary search. */
+ /* If we are using C++, D, or Java, demangle the name before doing a
+ lookup, so we can always binary search. */
if (lang == language_cplus)
{
demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
make_cleanup (xfree, demangled_name);
}
}
+ else if (lang == language_d)
+ {
+ demangled_name = d_demangle (name, 0);
+ if (demangled_name)
+ {
+ modified_name = demangled_name;
+ make_cleanup (xfree, demangled_name);
+ }
+ }
if (case_sensitivity == case_sensitive_off)
{
{
struct symbol *sym;
const struct language_defn *langdef;
- struct objfile *objfile;
/* 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
{
struct symbol *sym = NULL;
const struct block *function_block = block;
+
/* 'this' is only defined in the function's block, so find the
enclosing function block. */
for (; function_block && !BLOCK_FUNCTION (function_block);
return sym;
/* Now search all static file-level symbols. Not strictly correct,
- but more useful than an error. Do the symtabs first, then check
- the psymtabs. If a psymtab indicates the existence of the
- desired name as a file-level static, then do psymtab-to-symtab
- conversion on the fly and return the found symbol. */
+ but more useful than an error. */
+
+ return lookup_static_symbol_aux (name, domain);
+}
+
+/* Search all static file-level symbols for NAME from DOMAIN. Do the symtabs
+ first, then check the psymtabs. If a psymtab indicates the existence of the
+ desired name as a file-level static, then do psymtab-to-symtab conversion on
+ the fly and return the found symbol. */
+
+struct symbol *
+lookup_static_symbol_aux (const char *name, const domain_enum domain)
+{
+ struct objfile *objfile;
+ struct symbol *sym;
sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
if (sym != NULL)
if (sym != NULL)
return sym;
- if (language == language_cplus)
+ if (language == language_cplus || language == language_fortran)
{
sym = cp_lookup_symbol_imports (scope,
name,
const struct block *block;
struct symtab *s;
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_OBJFILES (objfile)
{
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, block_index);
- sym = lookup_block_symbol (block, name, domain);
- if (sym)
- {
- block_found = block;
- return fixup_symbol_section (sym, objfile);
- }
+ if (objfile->sf)
+ objfile->sf->qf->pre_expand_symtabs_matching (objfile,
+ block_index,
+ name, domain);
+
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ if (s->primary)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, block_index);
+ sym = lookup_block_symbol (block, name, domain);
+ if (sym)
+ {
+ block_found = block;
+ return fixup_symbol_section (sym, objfile);
+ }
+ }
}
return NULL;
struct symtab *symtab;
struct blockvector *bv;
const struct block *block;
- struct partial_symtab *ps;
struct symbol *sym;
if (!objfile->sf)
A Java class declaration also defines a typedef for the class.
Similarly, any Ada type declaration implicitly defines a typedef. */
if (symbol_language == language_cplus
+ || symbol_language == language_d
|| symbol_language == language_java
|| symbol_language == language_ada)
{
of the desired name as a global, then do psymtab-to-symtab
conversion on the fly and return the found symbol. */
- ALL_PRIMARY_SYMTABS (objfile, s)
+ ALL_OBJFILES (objfile)
{
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
- if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
- {
- return SYMBOL_TYPE (sym);
- }
+ if (objfile->sf)
+ objfile->sf->qf->pre_expand_symtabs_matching (objfile,
+ GLOBAL_BLOCK,
+ name, STRUCT_DOMAIN);
+
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ if (s->primary)
+ {
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
+ if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ {
+ return SYMBOL_TYPE (sym);
+ }
+ }
}
ALL_OBJFILES (objfile)
/* FIXME: What about languages without main() or specially linked
executables that have no main() ? */
-char *
+const char *
find_main_filename (void)
{
struct objfile *objfile;
- char *result, *name = main_name ();
+ char *name = main_name ();
ALL_OBJFILES (objfile)
{
+ const char *result;
+
if (!objfile->sf)
continue;
result = objfile->sf->qf->find_symbol_file (objfile, name);
struct blockvector *bv;
struct symtab *s = NULL;
struct symtab *best_s = NULL;
- struct partial_symtab *ps;
struct objfile *objfile;
struct program_space *pspace;
CORE_ADDR distance = 0;
if ((objfile->flags & OBJF_REORDERED) && objfile->sf)
{
struct symtab *result;
+
result
= objfile->sf->qf->find_pc_sect_symtab (objfile,
msymbol,
ALL_OBJFILES (objfile)
{
struct symtab *result;
+
if (!objfile->sf)
continue;
result = objfile->sf->qf->find_pc_sect_symtab (objfile,
If not found, return NULL. */
struct symtab *
-find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match)
+find_line_symtab (struct symtab *symtab, int line,
+ int *index, int *exact_match)
{
int exact = 0; /* Initialized here to avoid a compiler warning. */
find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
{
struct symtab_and_line sal;
+
sal = find_pc_line (pc, 0);
*startptr = sal.pc;
*endptr = sal.end;
{
CORE_ADDR func_start, func_end;
struct linetable *l;
- int ind, i, len;
- int best_lineno = 0;
- CORE_ADDR best_pc = func_addr;
+ int i;
/* Give up if this symbol has no lineinfo table. */
l = LINETABLE (symtab);
{
struct minimal_symbol *msymbol
= lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
+
if (msymbol == NULL)
{
do_cleanups (old_chain);
if (isalpha (*p) || *p == '_' || *p == '$')
{
char *q = p + 1;
+
while (isalnum (*q) || *q == '_' || *q == '$')
q++;
*end = q;
sources_info (char *ignore, int from_tty)
{
struct symtab *s;
- struct partial_symtab *ps;
struct objfile *objfile;
int first;
ALL_SYMTABS (objfile, s)
{
const char *fullname = symtab_to_fullname (s);
+
output_source_filename (fullname ? fullname : s->filename, &first);
}
printf_filtered ("\n\n");
search_symbols_file_matches (const char *filename, void *user_data)
{
struct search_symbols_data *data = user_data;
+
return file_matches (filename, data->files, data->nfiles);
}
search_symbols_name_matches (const char *symname, void *user_data)
{
struct search_symbols_data *data = user_data;
+
return data->regexp == NULL || re_exec (symname);
}
char *val;
int found_misc = 0;
static enum minimal_symbol_type types[]
- =
- {mst_data, mst_text, mst_abs, mst_unknown};
+ = {mst_data, mst_text, mst_abs, mst_unknown};
static enum minimal_symbol_type types2[]
- =
- {mst_bss, mst_file_text, mst_abs, mst_unknown};
+ = {mst_bss, mst_file_text, mst_abs, mst_unknown};
static enum minimal_symbol_type types3[]
- =
- {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
+ = {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
static enum minimal_symbol_type types4[]
- =
- {mst_file_bss, mst_text, mst_abs, mst_unknown};
+ = {mst_file_bss, mst_text, mst_abs, mst_unknown};
enum minimal_symbol_type ourtype;
enum minimal_symbol_type ourtype2;
enum minimal_symbol_type ourtype3;
and <TYPENAME> or <OPERATOR>. */
char *opend;
char *opname = operator_chars (regexp, &opend);
+
if (*opname)
{
int fix = -1; /* -1 means ok; otherwise number of spaces needed. */
+
if (isalpha (*opname) || *opname == '_' || *opname == '$')
{
/* There should 1 space between 'operator' and 'TYPENAME'. */
if (fix >= 0)
{
char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
+
sprintf (tmp, "operator%.*s%s", fix, " ", opname);
regexp = tmp;
}
{
struct symbol_search *prevtail = tail;
int nfound = 0;
+
b = BLOCKVECTOR_BLOCK (bv, i);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
struct symtab *real_symtab = SYMBOL_SYMTAB (sym);
+
QUIT;
if (file_matches (real_symtab->filename, files, nfiles)
&& ((regexp == NULL
|| re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
- && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+ && ((kind == VARIABLES_DOMAIN
+ && SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_UNRESOLVED
&& SYMBOL_CLASS (sym) != LOC_BLOCK
- && SYMBOL_CLASS (sym) != LOC_CONST)
+ /* 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
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM))
|| (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
{
static void
symtab_symbol_info (char *regexp, domain_enum kind, int from_tty)
{
- static char *classnames[]
- =
- {"variable", "function", "type", "method"};
+ static char *classnames[] = {"variable", "function", "type", "method"};
struct symbol_search *symbols;
struct symbol_search *p;
struct cleanup *old_chain;
struct cleanup *old_chain;
char *string = NULL;
int len = 0;
+ char **files = NULL;
+ int nfiles = 0;
+
+ if (regexp)
+ {
+ char *colon = strchr (regexp, ':');
+
+ if (colon && *(colon + 1) != ':')
+ {
+ int colon_index;
+ char * file_name;
+
+ colon_index = colon - regexp;
+ file_name = alloca (colon_index + 1);
+ memcpy (file_name, regexp, colon_index);
+ file_name[colon_index--] = 0;
+ while (isspace (file_name[colon_index]))
+ file_name[colon_index--] = 0;
+ files = &file_name;
+ nfiles = 1;
+ regexp = colon + 1;
+ while (isspace (*regexp)) regexp++;
+ }
+ }
- search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss);
+ search_symbols (regexp, FUNCTIONS_DOMAIN, nfiles, files, &ss);
old_chain = make_cleanup_free_search_symbols (ss);
make_cleanup (free_current_contents, &string);
int newlen = (strlen (p->symtab->filename)
+ strlen (SYMBOL_LINKAGE_NAME (p->symbol))
+ 4);
+
if (newlen > len)
{
string = xrealloc (string, newlen);
}
else
{
- int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol))
- + 3);
+ int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) + 3);
+
if (newlen > len)
{
string = xrealloc (string, newlen);
char *text, char *word)
{
int newsize;
- int i;
/* clip symbols that cannot match */
{
char *new;
+
if (word == sym_text)
{
new = xmalloc (strlen (symname) + 5);
void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
+
completion_list_add_name ((char *) name,
datum->sym_text, datum->sym_text_len,
datum->text, datum->word);
add_partial_symbol_name (const char *name, void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
+
completion_list_add_name ((char *) name,
datum->sym_text, datum->sym_text_len,
datum->text, datum->word);
}
char **
-default_make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list_break_on (char *text, char *word,
+ const char *break_on)
{
/* Problem: All of the symbols have to be copied because readline
frees them. I'm not going to worry about this; hopefully there
while (p > text)
{
if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
- || p[-1] == ':')
+ || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
--p;
else
break;
return (return_val);
}
+char **
+default_make_symbol_completion_list (char *text, char *word)
+{
+ return default_make_symbol_completion_list_break_on (text, word, "");
+}
+
/* Return a NULL terminated array of all symbols (regardless of class)
which begin by matching TEXT. If the answer is no symbols, then
the return value is an array which contains only a NULL pointer. */
else
{
const char *base_name = lbasename (filename);
+
if (base_name != filename
&& !filename_seen (base_name, 1, data->first)
#if HAVE_DOS_BASED_FILE_SYSTEM
if (prologue_sal.symtab->language != language_asm)
{
struct linetable *linetable = LINETABLE (prologue_sal.symtab);
- int exact;
int idx = 0;
/* Skip any earlier lines, and any end-of-sequence marker
{
struct linetable *l;
int len;
+
if (fullname != NULL
&& symtab_to_fullname (symtab) != NULL
&& FILENAME_CMP (fullname, symtab->fullname) != 0)
struct symtabs_and_lines
expand_line_sal (struct symtab_and_line sal)
{
- struct symtabs_and_lines ret, this_line;
+ struct symtabs_and_lines ret;
int i, j;
struct objfile *objfile;
- struct partial_symtab *psymtab;
- struct symtab *symtab;
int lineno;
int deleted = 0;
struct block **blocks = NULL;
blocks = alloca (ret.nelts * sizeof (struct block *));
for (i = 0; i < ret.nelts; ++i)
{
- struct blockvector *bl;
- struct block *b;
-
set_current_program_space (ret.sals[i].pspace);
filter[i] = 1;