[Ada] Add support for subprogram renamings

Consider the following declaration:

    function Foo (I : Integer) return Integer renames Pack.Bar;

As Foo is not materialized as a routine whose name is derived from Foo,
GDB currently cannot use it:

    (gdb) print foo(0)
    No definition of "foo" in current context.

However, compilers can emit DW_TAG_imported_declaration in order to
materialize the fact that Foo is actually another name for Pack.Bar.
This commit enhances the DWARF reader to record global renamings (it
used to put global ones in a static block) and enhances the Ada engine
to leverage this information during symbol lookup.

gdb/ChangeLog:

	* ada-lang.c: Include namespace.h
	(aux_add_nonlocal_symbols): Fix a function name in comment.
	(ada_add_block_renamings): New.
	(add_nonlocal_symbols): Add global renamings handling.
	(ada_lookup_symbol_list_worker): Move the symbol lookup part
	to...
	(ada_add_all_symbols): ... this new function.
	(ada_add_block_symbols): Try to match the input name against the
	"using directives list", perform a recursive symbol lookup on
	the matched declarations.
	* block.h (struct block): Move the_namespace to top-level as
	namespace_info. Remove the language_specific field.
	(BLOCK_NAMESPACE): Update access to the namespace_info field.
	* buildsym.h (using_directives): Rename into...
	(local_using_directives): ... this.
	(global_using_directives): New.
	(struct context_stack): Rename the using_directives field into
	local_using_directives.
	* buildsym.c (finish_block_internal): Deal with the proper
	using directives repository (local or global).
	(prepare_for_building): Reset local_using_directives. Assert
	that there is no pending global using directive.
	(reset_symtab_globals): Reset global_using_directives and
	local_using_directives.
	(end_symtab_get_static_block): Don't ignore symtabs that have
	only using directives.
	(push_context): Update references to local_using_directives.
	(buildsym_init): Do not reset using_directives.
	* cp-support.c: Include namespace.h.
	* cp-support.h (struct using_direct): Move to namespace.h.
	(cp_add_using_directives): Move to namespace.h.
	* cp-namespace.c: Include namespace.h
	(cp_add_using_directive): Move to namespace.c, rename it to
	add_using_directive, add a "using_directives" argument and use
	it as the pending using directives repository.  All callers
	updated.
	* dwarf2read.c (using_directives): New.
	(read_import_statement): Call using_directives.
	(read_func_scope): Update references to local_using_directives.
	(read_lexical_block_scope): Likewise.
	(read_namespace): Update the heading comment, call
	using_directives.
	* namespace.h: New file.
	* namespace.c: New file.
	* Makefile.in (SFILES): Add namespace.c.
	(COMMON_OBS): Add namespace.o

gdb/testsuite/ChangeLog:

	* gdb.ada/fun_renaming.exp: New testcase.
	* gdb.ada/fun_renaming/fun_renaming.adb: New file.
	* gdb.ada/fun_renaming/pack.adb: New file.
	* gdb.ada/fun_renaming/pack.ads: New file.

Tested on x86_64-linux.  Support for this in GCC is in the pipeline: see
<https://gcc.gnu.org/ml/gcc-patches/2015-07/msg02166.html>.
This commit is contained in:
Pierre-Marie de Rodat 2015-07-22 15:30:57 +02:00
parent 19c2883a9b
commit 22cee43f9a
15 changed files with 608 additions and 278 deletions

View file

@ -503,8 +503,15 @@ finish_block_internal (struct symbol *symbol, struct pending **listhead,
opblock = pblock;
}
block_set_using (block, using_directives, &objfile->objfile_obstack);
using_directives = NULL;
block_set_using (block,
(is_global
? global_using_directives
: local_using_directives),
&objfile->objfile_obstack);
if (is_global)
global_using_directives = NULL;
else
local_using_directives = NULL;
record_pending_block (objfile, block, opblock);
@ -1009,6 +1016,7 @@ prepare_for_building (const char *name, CORE_ADDR start_addr)
last_source_start_addr = start_addr;
local_symbols = NULL;
local_using_directives = NULL;
within_function = 0;
have_line_numbers = 0;
@ -1018,6 +1026,7 @@ prepare_for_building (const char *name, CORE_ADDR start_addr)
a symtab, or by the really_free_pendings cleanup. */
gdb_assert (file_symbols == NULL);
gdb_assert (global_symbols == NULL);
gdb_assert (global_using_directives == NULL);
gdb_assert (pending_macros == NULL);
gdb_assert (pending_addrmap == NULL);
gdb_assert (current_subfile == NULL);
@ -1177,8 +1186,10 @@ reset_symtab_globals (void)
set_last_source_file (NULL);
local_symbols = NULL;
local_using_directives = NULL;
file_symbols = NULL;
global_symbols = NULL;
global_using_directives = NULL;
/* We don't free pending_macros here because if the symtab was successfully
built then ownership was transferred to the symtab. */
@ -1281,7 +1292,8 @@ end_symtab_get_static_block (CORE_ADDR end_addr, int expandable, int required)
&& file_symbols == NULL
&& global_symbols == NULL
&& have_line_numbers == 0
&& pending_macros == NULL)
&& pending_macros == NULL
&& global_using_directives == NULL)
{
/* Ignore symtabs that have no functions with real debugging info. */
return NULL;
@ -1637,11 +1649,11 @@ push_context (int desc, CORE_ADDR valu)
newobj->locals = local_symbols;
newobj->old_blocks = pending_blocks;
newobj->start_addr = valu;
newobj->using_directives = using_directives;
newobj->local_using_directives = local_using_directives;
newobj->name = NULL;
local_symbols = NULL;
using_directives = NULL;
local_using_directives = NULL;
return newobj;
}
@ -1740,7 +1752,6 @@ get_last_source_file (void)
void
buildsym_init (void)
{
using_directives = NULL;
subfile_stack = NULL;
pending_addrmap_interesting = 0;
@ -1760,6 +1771,7 @@ buildsym_init (void)
gdb_assert (pending_blocks == NULL);
gdb_assert (file_symbols == NULL);
gdb_assert (global_symbols == NULL);
gdb_assert (global_using_directives == NULL);
gdb_assert (pending_macros == NULL);
gdb_assert (pending_addrmap == NULL);
gdb_assert (buildsym_compunit == NULL);