/* Symbol table lookup for the GNU debugger, GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "symtab.h"
#include "source.h"
#include "filenames.h" /* for FILENAME_CMP */
#include "objc-lang.h"
+#include "ada-lang.h"
#include "hashtab.h"
#include "gdb_stat.h"
#include <ctype.h>
#include "cp-abi.h"
+#include "observer.h"
/* Prototypes for local functions */
static void sources_info (char *, int);
-static void output_source_filename (char *, int *);
+static void output_source_filename (const char *, int *);
static int find_line_common (struct linetable *, int, int *);
if (full_path != NULL)
{
- const char *fp = symtab_to_fullname (s);
- if (FILENAME_CMP (full_path, fp) == 0)
- {
- return s;
- }
+ const char *fp = symtab_to_fullname (s);
+ if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+ {
+ return s;
+ }
}
if (real_path != NULL)
{
- char *rp = gdb_realpath (symtab_to_fullname (s));
- make_cleanup (xfree, rp);
- if (FILENAME_CMP (real_path, rp) == 0)
- {
- return s;
- }
+ 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)
+ {
+ return s;
+ }
+ }
}
}
return (NULL);
if (ps->readin)
- error ("Internal: readin %s pst for `%s' found when no symtab found.",
+ error (_("Internal: readin %s pst for `%s' found when no symtab found."),
ps->filename, name);
s = PSYMTAB_TO_SYMTAB (ps);
this symtab and use its absolute path. */
if (full_path != NULL)
{
- if (pst->fullname == NULL)
- source_full_path_of (pst->filename, &pst->fullname);
+ psymtab_to_fullname (pst);
if (pst->fullname != NULL
&& FILENAME_CMP (full_path, pst->fullname) == 0)
{
if (real_path != NULL)
{
char *rp = NULL;
- if (pst->fullname == NULL)
- source_full_path_of (pst->filename, &pst->fullname);
+ psymtab_to_fullname (pst);
if (pst->fullname != NULL)
{
rp = gdb_realpath (pst->fullname);
Choosing a much larger table size wastes memory, and saves only about
1% in symbol reading. */
- objfile->demangled_names_hash = htab_create_alloc_ex
+ objfile->demangled_names_hash = htab_create_alloc
(256, htab_hash_string, (int (*) (const void *, const void *)) streq,
- NULL, objfile->md, xmcalloc, xmfree);
+ NULL, xcalloc, xfree);
}
/* Try to determine the demangled name for a symbol, based on the
char *
symbol_natural_name (const struct general_symbol_info *gsymbol)
{
- if ((gsymbol->language == language_cplus
- || gsymbol->language == language_java
- || gsymbol->language == language_objc)
- && (gsymbol->language_specific.cplus_specific.demangled_name != NULL))
- {
- return gsymbol->language_specific.cplus_specific.demangled_name;
- }
- else
+ switch (gsymbol->language)
{
- return gsymbol->name;
+ case language_cplus:
+ case language_java:
+ case language_objc:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ break;
+ case language_ada:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ else
+ return ada_decode_symbol (gsymbol);
+ break;
+ default:
+ break;
}
+ return gsymbol->name;
}
/* Return the demangled name for a symbol based on the language for
char *
symbol_demangled_name (struct general_symbol_info *gsymbol)
{
- if (gsymbol->language == language_cplus
- || gsymbol->language == language_java
- || gsymbol->language == language_objc)
- return gsymbol->language_specific.cplus_specific.demangled_name;
-
- else
- return NULL;
+ switch (gsymbol->language)
+ {
+ case language_cplus:
+ case language_java:
+ case language_objc:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ break;
+ case language_ada:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ else
+ return ada_decode_symbol (gsymbol);
+ break;
+ default:
+ break;
+ }
+ return NULL;
}
/* Return the search name of a symbol---generally the demangled or
linkage name of the symbol, depending on how it will be searched for.
If there is no distinct demangled name, then returns the same value
(same pointer) as SYMBOL_LINKAGE_NAME. */
-char *symbol_search_name (const struct general_symbol_info *gsymbol) {
- return symbol_natural_name (gsymbol);
+char *
+symbol_search_name (const struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language == language_ada)
+ return gsymbol->name;
+ else
+ return symbol_natural_name (gsymbol);
}
/* Initialize the structure fields to zero values. */
modified_name = name;
- /* If we are using C++ language, demangle the name before doing a lookup, so
+ /* If we are using C++ or Java, demangle the name before doing a lookup, so
we can always binary search. */
if (current_language->la_language == language_cplus)
{
needtofreename = 1;
}
}
+ else if (current_language->la_language == language_java)
+ {
+ demangled_name = cplus_demangle (name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ needtofreename = 1;
+ }
+ }
if (case_sensitivity == case_sensitive_off)
{
STATIC_BLOCK : GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
- error ("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>).",
+ error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
block_index == GLOBAL_BLOCK ? "global" : "static",
name, ps->filename, name, name);
}
{
center = bottom + (top - bottom) / 2;
if (!(center < top))
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
if (!do_linear_search
&& (SYMBOL_LANGUAGE (*center) == language_java))
{
}
}
if (!(top == bottom))
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
while (top <= real_top
&& (linkage_name != NULL
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
- error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+ error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+(if a template, try specifying an instantiation: %s<type>)."),
name, ps->filename, name, name);
}
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
- error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+ error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+(if a template, try specifying an instantiation: %s<type>)."),
name, ps->filename, name, name);
}
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
/* Might want to error() here (in case symtab is corrupt and
will cause a core dump), but maybe we can successfully
continue, so let's not. */
- warning ("\
-(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n",
+ warning (_("\
+(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n"),
paddr_nz (pc));
s = PSYMTAB_TO_SYMTAB (ps);
}
else if (p[1] == '[')
{
if (p[2] == ']')
- error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+ error (_("mismatched quoting on brackets, try 'operator\\[\\]'"));
else if (p[2] == '\\' && p[3] == ']')
{
*end = p + 4; /* 'operator\[\]' */
return p;
}
else
- error ("nothing is allowed between '[' and ']'");
+ error (_("nothing is allowed between '[' and ']'"));
}
else
{
return p;
case '(':
if (p[1] != ')')
- error ("`operator ()' must be specified without whitespace in `()'");
+ error (_("`operator ()' must be specified without whitespace in `()'"));
*end = p + 2;
return p;
case '?':
if (p[1] != ':')
- error ("`operator ?:' must be specified without whitespace in `?:'");
+ error (_("`operator ?:' must be specified without whitespace in `?:'"));
*end = p + 2;
return p;
case '[':
if (p[1] != ']')
- error ("`operator []' must be specified without whitespace in `[]'");
+ error (_("`operator []' must be specified without whitespace in `[]'"));
*end = p + 2;
return p;
default:
- error ("`operator %s' not supported", p);
+ error (_("`operator %s' not supported"), p);
break;
}
NAME is the name to print and *FIRST is nonzero if this is the first
name printed. Set *FIRST to zero. */
static void
-output_source_filename (char *name, int *first)
+output_source_filename (const char *name, int *first)
{
/* Since a single source file can result in several partial symbol
tables, we need to avoid printing it more than once. Note: if
if (!have_full_symbols () && !have_partial_symbols ())
{
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
}
printf_filtered ("Source files for which symbols have been read in:\n\n");
first = 1;
ALL_SYMTABS (objfile, s)
{
- output_source_filename (s->filename, &first);
+ const char *fullname = symtab_to_fullname (s);
+ output_source_filename (fullname ? fullname : s->filename, &first);
}
printf_filtered ("\n\n");
{
if (!ps->readin)
{
- output_source_filename (ps->filename, &first);
+ const char *fullname = psymtab_to_fullname (ps);
+ output_source_filename (fullname ? fullname : ps->filename, &first);
}
}
printf_filtered ("\n");
struct cleanup *old_chain = NULL;
if (kind < VARIABLES_DOMAIN)
- error ("must search on specific domain");
+ error (_("must search on specific domain"));
ourtype = types[(int) (kind - VARIABLES_DOMAIN)];
ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)];
}
if (0 != (val = re_comp (regexp)))
- error ("Invalid regexp (%s): %s", val, regexp);
+ error (_("Invalid regexp (%s): %s"), val, regexp);
}
/* Search through the partial symtabs *first* for all symbols
char *tmp;
if (TARGET_ADDR_BIT <= 32)
- tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
- & (CORE_ADDR) 0xffffffff,
- "08l");
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+ & (CORE_ADDR) 0xffffffff,
+ 8);
else
- tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
- "016l");
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+ 16);
printf_filtered ("%s %s\n",
tmp, SYMBOL_PRINT_NAME (msymbol));
}
struct symtab_and_line cursal;
if (string == 0)
- error ("Empty line specification.");
+ error (_("Empty line specification."));
/* We use whatever is set as the current source line. We do not try
and get a default or it will recursively call us! */
(char ***) NULL, NULL);
if (*string)
- error ("Junk at end of line specification: %s", string);
+ error (_("Junk at end of line specification: %s"), string);
return sals;
}
}
}
+/* Deduce the name of the main procedure, and set NAME_OF_MAIN
+ accordingly. */
+
+static void
+find_main_name (void)
+{
+ char *new_main_name;
+
+ /* Try to see if the main procedure is in Ada. */
+ /* FIXME: brobecker/2005-03-07: Another way of doing this would
+ be to add a new method in the language vector, and call this
+ method for each language until one of them returns a non-empty
+ name. This would allow us to remove this hard-coded call to
+ an Ada function. It is not clear that this is a better approach
+ at this point, because all methods need to be written in a way
+ such that false positives never be returned. For instance, it is
+ important that a method does not return a wrong name for the main
+ procedure if the main procedure is actually written in a different
+ language. It is easy to guaranty this with Ada, since we use a
+ special symbol generated only when the main in Ada to find the name
+ of the main procedure. It is difficult however to see how this can
+ be guarantied for languages such as C, for instance. This suggests
+ that order of call for these methods becomes important, which means
+ a more complicated approach. */
+ new_main_name = ada_main_name ();
+ if (new_main_name != NULL)
+ {
+ set_main_name (new_main_name);
+ return;
+ }
+
+ /* The languages above didn't identify the name of the main procedure.
+ Fallback to "main". */
+ set_main_name ("main");
+}
+
char *
main_name (void)
{
- if (name_of_main != NULL)
- return name_of_main;
- else
- return "main";
+ if (name_of_main == NULL)
+ find_main_name ();
+
+ return name_of_main;
}
+/* Handle ``executable_changed'' events for the symtab module. */
+
+static void
+symtab_observer_executable_changed (void *unused)
+{
+ /* NAME_OF_MAIN may no longer be the same, so reset it for now. */
+ set_main_name (NULL);
+}
void
_initialize_symtab (void)
{
- add_info ("variables", variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_info ("variables", variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
if (dbx_commands)
- add_com ("whereis", class_info, variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_com ("whereis", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
add_info ("functions", functions_info,
- "All function names, or those matching REGEXP.");
+ _("All function names, or those matching REGEXP."));
/* FIXME: This command has at least the following problems:
I also think "ptype" or "whatis" is more likely to be useful (but if
there is much disagreement "info types" can be fixed). */
add_info ("types", types_info,
- "All type names, or those matching REGEXP.");
+ _("All type names, or those matching REGEXP."));
add_info ("sources", sources_info,
- "Source files in the program.");
+ _("Source files in the program."));
add_com ("rbreak", class_breakpoint, rbreak_command,
- "Set a breakpoint for all functions matching REGEXP.");
+ _("Set a breakpoint for all functions matching REGEXP."));
if (xdb_commands)
{
- add_com ("lf", class_info, sources_info, "Source files in the program");
- add_com ("lg", class_info, variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_com ("lf", class_info, sources_info,
+ _("Source files in the program"));
+ add_com ("lg", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
}
/* Initialize the one built-in type that isn't language dependent... */
builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
"<unknown type>", (struct objfile *) NULL);
+
+ observer_attach_executable_changed (symtab_observer_executable_changed);
}