/* Symbol table lookup for the GNU debugger, GDB.
- Copyright (C) 1986-2013 Free Software Foundation, Inc.
+ Copyright (C) 1986-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "macrotab.h"
#include "macroscope.h"
-#include "psymtab.h"
#include "parser-defs.h"
/* Prototypes for local functions */
/* */
+/* Program space key for finding name and language of "main". */
+
+static const struct program_space_data *main_progspace_key;
+
+/* Type of the data stored on the program space. */
+
+struct main_info
+{
+ /* Name of "main". */
+
+ char *name_of_main;
+
+ /* Language of "main". */
+
+ enum language language_of_main;
+};
+
/* When non-zero, print debugging messages related to symtab creation. */
unsigned int symtab_create_debug = 0;
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. */
+
+ /* Check for Ada symbols last. See comment below explaining why. */
+
+ if (gsymbol->language == language_auto)
+ {
+ const char *demangled = ada_decode (mangled);
+
+ if (demangled != mangled && demangled != NULL && demangled[0] != '<')
+ {
+ /* Set the gsymbol language to Ada, but still return NULL.
+ Two reasons for that:
+
+ 1. For Ada, we prefer computing the symbol's decoded name
+ on the fly rather than pre-compute it, in order to save
+ memory (Ada projects are typically very large).
+
+ 2. There are some areas in the definition of the GNAT
+ encoding where, with a bit of bad luck, we might be able
+ to decode a non-Ada symbol, generating an incorrect
+ demangled name (Eg: names ending with "TB" for instance
+ are identified as task bodies and so stripped from
+ the decoded name returned).
+
+ Returning NULL, here, helps us get a little bit of
+ the best of both worlds. Because we're last, we should
+ not affect any of the other languages that were able to
+ demangle the symbol before us; we get to correctly tag
+ Ada symbols as such; and even if we incorrectly tagged
+ a non-Ada symbol, which should be rare, any routing
+ through the Ada language should be transparent (Ada
+ tries to behave much like C/C++ with non-Ada symbols). */
+ gsymbol->language = language_ada;
+ return NULL;
+ }
+ }
+
return NULL;
}
clear_filename_seen_cache (data.filename_seen_cache);
data.first = 1;
- map_partial_symbol_filenames (output_partial_symbol_filename, &data,
- 1 /*need_fullname*/);
+ map_symbol_filenames (output_partial_symbol_filename, &data,
+ 1 /*need_fullname*/);
printf_filtered ("\n");
do_cleanups (cleanups);
datum.nfiles = nfiles;
datum.files = files;
- ALL_OBJFILES (objfile)
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile,
- (nfiles == 0
- ? NULL
- : search_symbols_file_matches),
- search_symbols_name_matches,
- kind,
- &datum);
- }
+ expand_symtabs_matching ((nfiles == 0
+ ? NULL
+ : search_symbols_file_matches),
+ search_symbols_name_matches,
+ kind, &datum);
/* Here, we search through the minimal symbol tables for functions
and variables that match, and force their symbols to be read.
}
/* Type of the user_data argument passed to add_macro_name or
- expand_partial_symbol_name. The contents are simply whatever is
+ symbol_completion_matcher. The contents are simply whatever is
needed by completion_list_add_name. */
struct add_name_data
{
datum->text, datum->word);
}
-/* A callback for expand_partial_symbol_names. */
+/* A callback for expand_symtabs_matching. */
static int
-expand_partial_symbol_name (const char *name, void *user_data)
+symbol_completion_matcher (const char *name, void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
/* Look through the partial symtabs for all symbols which begin
by matching SYM_TEXT. Expand all CUs that you find to the list.
The real names will get added by COMPLETION_LIST_ADD_SYMBOL below. */
- expand_partial_symbol_names (expand_partial_symbol_name, &datum);
+ expand_symtabs_matching (NULL, symbol_completion_matcher, ALL_DOMAIN,
+ &datum);
/* At this point scan through the misc symbol vectors and add each
symbol you find to the list. Eventually we want to ignore
datum.word = word;
datum.text_len = text_len;
datum.list = &list;
- map_partial_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
- 0 /*need_fullname*/);
+ map_symbol_filenames (maybe_add_partial_symtab_filename, &datum,
+ 0 /*need_fullname*/);
do_cleanups (cache_cleanup);
discard_cleanups (back_to);
}
\f
/* Track MAIN */
-static char *name_of_main;
-enum language language_of_main = language_unknown;
-void
-set_main_name (const char *name)
+/* Return the "main_info" object for the current program space. If
+ the object has not yet been created, create it and fill in some
+ default values. */
+
+static struct main_info *
+get_main_info (void)
+{
+ struct main_info *info = program_space_data (current_program_space,
+ main_progspace_key);
+
+ if (info == NULL)
+ {
+ /* It may seem strange to store the main name in the progspace
+ and also in whatever objfile happens to see a main name in
+ its debug info. The reason for this is mainly historical:
+ gdb returned "main" as the name even if no function named
+ "main" was defined the program; and this approach lets us
+ keep compatibility. */
+ info = XCNEW (struct main_info);
+ info->language_of_main = language_unknown;
+ set_program_space_data (current_program_space, main_progspace_key,
+ info);
+ }
+
+ return info;
+}
+
+/* A cleanup to destroy a struct main_info when a progspace is
+ destroyed. */
+
+static void
+main_info_cleanup (struct program_space *pspace, void *data)
+{
+ struct main_info *info = data;
+
+ if (info != NULL)
+ xfree (info->name_of_main);
+ xfree (info);
+}
+
+static void
+set_main_name (const char *name, enum language lang)
{
- if (name_of_main != NULL)
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main != NULL)
{
- xfree (name_of_main);
- name_of_main = NULL;
- language_of_main = language_unknown;
+ xfree (info->name_of_main);
+ info->name_of_main = NULL;
+ info->language_of_main = language_unknown;
}
if (name != NULL)
{
- name_of_main = xstrdup (name);
- language_of_main = language_unknown;
+ info->name_of_main = xstrdup (name);
+ info->language_of_main = lang;
}
}
find_main_name (void)
{
const char *new_main_name;
+ struct objfile *objfile;
+
+ /* First check the objfiles to see whether a debuginfo reader has
+ picked up the appropriate main name. Historically the main name
+ was found in a more or less random way; this approach instead
+ relies on the order of objfile creation -- which still isn't
+ guaranteed to get the correct answer, but is just probably more
+ accurate. */
+ ALL_OBJFILES (objfile)
+ {
+ if (objfile->per_bfd->name_of_main != NULL)
+ {
+ set_main_name (objfile->per_bfd->name_of_main,
+ objfile->per_bfd->language_of_main);
+ return;
+ }
+ }
/* Try to see if the main procedure is in Ada. */
/* FIXME: brobecker/2005-03-07: Another way of doing this would
new_main_name = ada_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_ada);
return;
}
new_main_name = go_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_go);
return;
}
new_main_name = pascal_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_pascal);
return;
}
/* The languages above didn't identify the name of the main procedure.
Fallback to "main". */
- set_main_name ("main");
+ set_main_name ("main", language_unknown);
}
char *
main_name (void)
{
- if (name_of_main == NULL)
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main == NULL)
+ find_main_name ();
+
+ return info->name_of_main;
+}
+
+/* Return the language of the main function. If it is not known,
+ return language_unknown. */
+
+enum language
+main_language (void)
+{
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main == NULL)
find_main_name ();
- return name_of_main;
+ return info->language_of_main;
}
/* Handle ``executable_changed'' events for the symtab module. */
symtab_observer_executable_changed (void)
{
/* NAME_OF_MAIN may no longer be the same, so reset it for now. */
- set_main_name (NULL);
+ set_main_name (NULL, language_unknown);
}
/* Return 1 if the supplied producer string matches the ARM RealView
{
initialize_ordinary_address_classes ();
+ main_progspace_key
+ = register_program_space_data_with_cleanup (NULL, main_info_cleanup);
+
add_info ("variables", variables_info, _("\
All global and static variable names, or those matching REGEXP."));
if (dbx_commands)