diff options
author | Pierre-Marie de Rodat <derodat@adacore.com> | 2015-07-22 15:30:57 +0200 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2015-08-13 09:33:42 +0200 |
commit | 22cee43f9af76fc4c10c3d4018a9ada6d7c5c1a5 (patch) | |
tree | ed55bfc1342e44a3889337a8106eb75c21ccfad1 /gdb/dwarf2read.c | |
parent | 19c2883a9b92e2be695368e19788fd0210d732d4 (diff) | |
download | binutils-22cee43f9af76fc4c10c3d4018a9ada6d7c5c1a5.zip binutils-22cee43f9af76fc4c10c3d4018a9ada6d7c5c1a5.tar.gz binutils-22cee43f9af76fc4c10c3d4018a9ada6d7c5c1a5.tar.bz2 |
[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>.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 7e79342..7ae50f7 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -69,6 +69,7 @@ #include "source.h" #include "filestuff.h" #include "build-id.h" +#include "namespace.h" #include <fcntl.h> #include <sys/types.h> @@ -1635,6 +1636,8 @@ static void read_namespace (struct die_info *die, struct dwarf2_cu *); static void read_module (struct die_info *die, struct dwarf2_cu *cu); +static struct using_direct **using_directives (enum language); + static void read_import_statement (struct die_info *die, struct dwarf2_cu *); static int read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu); @@ -8863,6 +8866,24 @@ read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu) return 0; } +/* Return the using directives repository (global or local?) to use in the + current context for LANGUAGE. + + For Ada, imported declarations can materialize renamings, which *may* be + global. However it is impossible (for now?) in DWARF to distinguish + "external" imported declarations and "static" ones. As all imported + declarations seem to be static in all other languages, make them all CU-wide + global only in Ada. */ + +static struct using_direct ** +using_directives (enum language language) +{ + if (language == language_ada && context_stack_depth == 0) + return &global_using_directives; + else + return &local_using_directives; +} + /* Read the import statement specified by the given die and record it. */ static void @@ -8999,13 +9020,14 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) process_die (child_die, cu); } - cp_add_using_directive (import_prefix, - canonical_name, - import_alias, - imported_declaration, - excludes, - 0, - &objfile->objfile_obstack); + add_using_directive (using_directives (cu->language), + import_prefix, + canonical_name, + import_alias, + imported_declaration, + excludes, + 0, + &objfile->objfile_obstack); do_cleanups (cleanups); } @@ -11485,7 +11507,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) when we finish processing a function scope, we may need to go back to building a containing block's symbol lists. */ local_symbols = newobj->locals; - using_directives = newobj->using_directives; + local_using_directives = newobj->local_using_directives; /* If we've finished processing a top-level function, subsequent symbols go in the file symbol list. */ @@ -11531,7 +11553,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) inherit_abstract_dies (die, cu); newobj = pop_context (); - if (local_symbols != NULL || using_directives != NULL) + if (local_symbols != NULL || local_using_directives != NULL) { struct block *block = finish_block (0, &local_symbols, newobj->old_blocks, @@ -11550,7 +11572,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) dwarf2_record_block_ranges (die, block, baseaddr, cu); } local_symbols = newobj->locals; - using_directives = newobj->using_directives; + local_using_directives = newobj->local_using_directives; } /* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */ @@ -14076,7 +14098,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu) return set_die_type (die, type, cu); } -/* Read a C++ namespace. */ +/* Read a namespace scope. */ static void read_namespace (struct die_info *die, struct dwarf2_cu *cu) @@ -14100,8 +14122,9 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) { const char *previous_prefix = determine_prefix (die, cu); - cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL, - NULL, NULL, 0, &objfile->objfile_obstack); + add_using_directive (using_directives (cu->language), + previous_prefix, TYPE_NAME (type), NULL, + NULL, NULL, 0, &objfile->objfile_obstack); } } |