This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] [Ada] Add support for subprogram renamings
- From: Doug Evans <xdje42 at gmail dot com>
- To: Pierre-Marie de Rodat <derodat at adacore dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Sun, 26 Jul 2015 02:29:49 -0700
- Subject: Re: [PATCH] [Ada] Add support for subprogram renamings
- Authentication-results: sourceware.org; auth=none
- References: <1437854144-31928-1-git-send-email-derodat at adacore dot com>
Pierre-Marie de Rodat <derodat@adacore.com> writes:
> 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.
Hi.
A few nits inline, grep for ====.
> gdb/ChangeLog:
>
> * ada-lang.c: Include cp-support.h
ada-foo including cp-foo?
We need to clean this up.
Things are even muddier as this stuff is recorded in
block.language_specific.cplus_specific, so cleaning this up now will be good.
I gather cp-support.h is needed here for struct using_direct.
I think (at least) three things need to happen.
1) Move the definition of struct using_direct out of cp-support.h.
2) Move the definition of cp_add_using_directive out of cp-namespace.c.
And delete the leading "cp_".
3) Reorg block.language_specific.
For the first two I'd be ok with lang-support.[ch].
Yeah, it'll be a small file for now, but that's ok IMO.
Alternatives are language.[ch] or block.[ch].
For (3), in the absence of needing anything more at the moment,
I'd be ok with replacing:
union
{
struct
{
/* Contains information about namespace-related info relevant to
this block: using directives and the current namespace
scope. */
struct block_namespace_info *the_namespace;
}
cplus_specific;
}
language_specific;
with just:
/* Contains information about namespace-related info relevant to
this block: using directives and the current namespace scope. */
struct block_namespace_info *the_namespace;
though I'd probably rename "the_namespace" to "namespace_info"
or some such.
> (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.
> * 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): Assert that there is no pending global
> using directive.
> (reset_symtab_globals): Reset global_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): Likewise.
> * cp-support.h (cp_add_using_directives): Add a
> "using_directives" argument.
> * cp-namespace.c (cp_add_using_directive): Add a
> "using_directives" argument and use it as the pending using
> directives repository.
====
Missing "All callers updated."
> (cp_scan_for_anonymous_namespaces): Update call to
> cp_add_using_directive.
====
Don't write individual changelog entries for updates to function calls.
Instead, just write "All callers updated." at the description of
the function that was changed.
> * dwarf2read.c (read_import_statement): Likewise.
> (read_namespace): Likewise.
> (read_func_scope): Update references to local_using_directives.
> (read_lexical_block_scope): Likewise.
>
> 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>.
> ...
>
> diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
> index 06c72ee..c313fa8 100644
> --- a/gdb/ada-lang.c
> +++ b/gdb/ada-lang.c
> @@ -53,6 +53,7 @@
> #include "stack.h"
> #include "gdb_vecs.h"
> #include "typeprint.h"
> +#include "cp-support.h"
>
> #include "psymtab.h"
> #include "value.h"
> @@ -108,6 +109,9 @@ static void ada_add_block_symbols (struct obstack *,
> const struct block *, const char *,
> domain_enum, struct objfile *, int);
>
> +static void ada_add_all_symbols (struct obstack *, const struct block *,
> + const char *, domain_enum, int, int *);
> +
> static int is_nonfunction (struct ada_symbol_info *, int);
>
> static void add_defn_to_vec (struct obstack *, struct symbol *,
> @@ -5288,7 +5292,7 @@ struct match_data
> int found_sym;
> };
>
> -/* A callback for add_matching_symbols that adds SYM, found in BLOCK,
> +/* A callback for add_nonlocal_symbols that adds SYM, found in BLOCK,
> to a list of symbols. DATA0 is a pointer to a struct match_data *
> containing the obstack that collects the symbol list, the file that SYM
> must come from, a flag indicating whether a non-argument symbol has
> @@ -5328,6 +5332,62 @@ aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0)
> return 0;
> }
>
> +/* Helper for add_nonlocal_symbols. Find symbols in DOMAIN which are targetted
> + by renamings matching NAME in BLOCK. Add these symbols to OBSTACKP. If
> + WILD_MATCH_P is nonzero, perform the naming matching in "wild" mode (see
> + function "wild_match" for more information). Return whether we found such
> + symbols. */
> +
> +static int
> +ada_add_block_renamings (struct obstack *obstackp,
> + const struct block *block,
> + const char *name,
> + domain_enum domain,
> + int wild_match_p)
> +{
> + struct using_direct *renaming;
> + int defns_mark = num_defns_collected (obstackp);
> +
> + for (renaming = block_using (block);
> + renaming != NULL;
> + renaming = renaming->next)
> + {
> + const char *r_name;
> + int name_match;
> +
> + /* Avoid infinite recursions: skip this renaming if we are actually
> + already traversing it.
> +
> + Currently, symbol lookup in Ada don't use the namespace machinery from
> + C++/Fortran support: skip namespace imports that use them. */
> + if (renaming->searched
> + || (renaming->import_src != NULL
> + && renaming->import_src[0] != '\0')
> + || (renaming->import_dest != NULL
> + && renaming->import_dest[0] != '\0'))
> + continue;
> + renaming->searched = 1;
> +
> + /* TODO: here, we perform another name-based symbol lookup, which can
> + pull its own multiple overloads. In theory, we should be able to do
> + better in this case since, in DWARF, DW_AT_import is a DIE reference,
> + not a simple name. But in order to do this, we would need to enhance
> + the DWARF reader to associate a symbol to this renaming, instead of a
> + name. So, for now, we do something simpler: re-use the C++/Fortran
> + namespace machinery. */
> + r_name = (renaming->alias != NULL
> + ? renaming->alias
> + : renaming->declaration);
> + name_match
> + = wild_match_p ? wild_match (r_name, name) : strcmp (r_name, name);
> + if (name_match == 0)
> + ada_add_all_symbols (obstackp, block, renaming->declaration, domain,
> + 1, NULL);
> + renaming->searched = 0;
> + }
> + return num_defns_collected (obstackp) != defns_mark;
> +}
> +
> /* Implements compare_names, but only applying the comparision using
> the given CASING. */
>
> @@ -5423,6 +5483,7 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
> int is_wild_match)
> {
> struct objfile *objfile;
> + struct compunit_symtab *cu;
> struct match_data data;
>
> memset (&data, 0, sizeof data);
> @@ -5440,6 +5501,16 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
> objfile->sf->qf->map_matching_symbols (objfile, name, domain, global,
> aux_add_nonlocal_symbols, &data,
> full_match, compare_names);
> +
> + ALL_OBJFILE_COMPUNITS (objfile, cu)
> + {
> + const struct block *global_block
> + = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK);
> +
> + if (ada_add_block_renamings (obstackp, global_block , name, domain,
> + is_wild_match))
> + data.found_sym = 1;
> + }
> }
>
> if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
> @@ -5459,43 +5530,35 @@ add_nonlocal_symbols (struct obstack *obstackp, const char *name,
> }
> }
>
> -/* Find symbols in DOMAIN matching NAME0, in BLOCK0 and, if full_search is
> +/* Find symbols in DOMAIN matching NAME, in BLOCK and, if FULL_SEARCH is
> non-zero, enclosing scope and in global scopes, returning the number of
> - matches.
> - Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples,
> - indicating the symbols found and the blocks and symbol tables (if
> - any) in which they were found. This vector is transient---good only to
> - the next call of ada_lookup_symbol_list.
> + matches. Add these to OBSTACKP.
>
> - When full_search is non-zero, any non-function/non-enumeral
> - symbol match within the nest of blocks whose innermost member is BLOCK0,
> + When FULL_SEARCH is non-zero, any non-function/non-enumeral
> + symbol match within the nest of blocks whose innermost member is BLOCK,
> is the one match returned (no other matches in that or
> enclosing blocks is returned). If there are any matches in or
> - surrounding BLOCK0, then these alone are returned.
> + surrounding BLOCK, then these alone are returned.
>
> Names prefixed with "standard__" are handled specially: "standard__"
> - is first stripped off, and only static and global symbols are searched. */
> + is first stripped off, and only static and global symbols are searched.
>
> -static int
> -ada_lookup_symbol_list_worker (const char *name0, const struct block *block0,
> - domain_enum domain,
> - struct ada_symbol_info **results,
> - int full_search)
> + If MADE_GLOBAL_LOOKUP_P is non-null, set it before return to whether we had
> + to lookup global symbols. */
> +
> +static void
> +ada_add_all_symbols (struct obstack *obstackp,
> + const struct block *block,
> + const char *name,
> + domain_enum domain,
> + int full_search,
> + int *made_global_lookup_p)
> {
> struct symbol *sym;
> - const struct block *block;
> - const char *name;
> - const int wild_match_p = should_use_wild_match (name0);
> - int syms_from_global_search = 0;
> - int ndefns;
> -
> - obstack_free (&symbol_list_obstack, NULL);
> - obstack_init (&symbol_list_obstack);
> -
> - /* Search specified block and its superiors. */
> + const int wild_match_p = should_use_wild_match (name);
>
> - name = name0;
> - block = block0;
> + if (made_global_lookup_p)
> + *made_global_lookup_p = 0;
>
> /* Special case: If the user specifies a symbol name inside package
> Standard, do a non-wild matching of the symbol name without
> @@ -5504,10 +5567,10 @@ ada_lookup_symbol_list_worker (const char *name0, const struct block *block0,
> using, for instance, Standard.Constraint_Error when Constraint_Error
> is ambiguous (due to the user defining its own Constraint_Error
> entity inside its program). */
> - if (startswith (name0, "standard__"))
> + if (startswith (name, "standard__"))
> {
> block = NULL;
> - name = name0 + sizeof ("standard__") - 1;
> + name = name + sizeof ("standard__") - 1;
> }
>
> /* Check the non-global symbols. If we have ANY match, then we're done. */
> @@ -5515,61 +5578,88 @@ ada_lookup_symbol_list_worker (const char *name0, const struct block *block0,
> if (block != NULL)
> {
> if (full_search)
> - {
> - ada_add_local_symbols (&symbol_list_obstack, name, block,
> - domain, wild_match_p);
> - }
> + ada_add_local_symbols (obstackp, name, block, domain, wild_match_p);
> else
> {
> /* In the !full_search case we're are being called by
> ada_iterate_over_symbols, and we don't want to search
> superblocks. */
> - ada_add_block_symbols (&symbol_list_obstack, block, name,
> - domain, NULL, wild_match_p);
> + ada_add_block_symbols (obstackp, block, name, domain, NULL,
> + wild_match_p);
> }
> - if (num_defns_collected (&symbol_list_obstack) > 0 || !full_search)
> - goto done;
> + if (num_defns_collected (obstackp) > 0 || !full_search)
> + return;
> }
>
> /* No non-global symbols found. Check our cache to see if we have
> already performed this search before. If we have, then return
> the same result. */
>
> - if (lookup_cached_symbol (name0, domain, &sym, &block))
> + if (lookup_cached_symbol (name, domain, &sym, &block))
> {
> if (sym != NULL)
> - add_defn_to_vec (&symbol_list_obstack, sym, block);
> - goto done;
> + add_defn_to_vec (obstackp, sym, block);
> + return;
> }
>
> - syms_from_global_search = 1;
> + if (made_global_lookup_p)
> + *made_global_lookup_p = 1;
>
> /* Search symbols from all global blocks. */
>
> - add_nonlocal_symbols (&symbol_list_obstack, name, domain, 1,
> - wild_match_p);
> + add_nonlocal_symbols (obstackp, name, domain, 1, wild_match_p);
>
> /* Now add symbols from all per-file blocks if we've gotten no hits
> (not strictly correct, but perhaps better than an error). */
>
> - if (num_defns_collected (&symbol_list_obstack) == 0)
> - add_nonlocal_symbols (&symbol_list_obstack, name, domain, 0,
> - wild_match_p);
> + if (num_defns_collected (obstackp) == 0)
> + add_nonlocal_symbols (obstackp, name, domain, 0, wild_match_p);
> +}
> +
> +/* Find symbols in DOMAIN matching NAME, in BLOCK and, if full_search is
> + non-zero, enclosing scope and in global scopes, returning the number of
> + matches.
> + Sets *RESULTS to point to a vector of (SYM,BLOCK) tuples,
> + indicating the symbols found and the blocks and symbol tables (if
> + any) in which they were found. This vector is transient---good only to
> + the next call of ada_lookup_symbol_list.
> +
> + When full_search is non-zero, any non-function/non-enumeral
> + symbol match within the nest of blocks whose innermost member is BLOCK,
> + is the one match returned (no other matches in that or
> + enclosing blocks is returned). If there are any matches in or
> + surrounding BLOCK, then these alone are returned.
> +
> + Names prefixed with "standard__" are handled specially: "standard__"
> + is first stripped off, and only static and global symbols are searched. */
> +
> +static int
> +ada_lookup_symbol_list_worker (const char *name, const struct block *block,
> + domain_enum domain,
> + struct ada_symbol_info **results,
> + int full_search)
> +{
> + const int wild_match_p = should_use_wild_match (name);
> + int syms_from_global_search;
> + int ndefns;
> +
> + obstack_free (&symbol_list_obstack, NULL);
> + obstack_init (&symbol_list_obstack);
> + ada_add_all_symbols (&symbol_list_obstack, block, name, domain,
> + full_search, &syms_from_global_search);
>
> -done:
> ndefns = num_defns_collected (&symbol_list_obstack);
> *results = defns_collected (&symbol_list_obstack, 1);
>
> ndefns = remove_extra_symbols (*results, ndefns);
>
> if (ndefns == 0 && full_search && syms_from_global_search)
> - cache_symbol (name0, domain, NULL, NULL);
> + cache_symbol (name, domain, NULL, NULL);
>
> if (ndefns == 1 && full_search && syms_from_global_search)
> - cache_symbol (name0, domain, (*results)[0].sym, (*results)[0].block);
> -
> - ndefns = remove_irrelevant_renamings (*results, ndefns, block0);
> + cache_symbol (name, domain, (*results)[0].sym, (*results)[0].block);
>
> + ndefns = remove_irrelevant_renamings (*results, ndefns, block);
> return ndefns;
> }
>
> @@ -6036,6 +6126,11 @@ ada_add_block_symbols (struct obstack *obstackp,
> }
> }
>
> + /* Handle renamings. */
> +
> + if (ada_add_block_renamings (obstackp, block, name, domain, wild))
> + found_sym = 1;
> +
> if (!found_sym && arg_sym != NULL)
> {
> add_defn_to_vec (obstackp,
> diff --git a/gdb/buildsym.c b/gdb/buildsym.c
> index 2a24a25..ac9c447 100644
> --- a/gdb/buildsym.c
> +++ b/gdb/buildsym.c
> @@ -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);
>
> @@ -1018,6 +1025,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);
====
I've put a lot of time into cleaning up buildsym.[ch] but we
still have a long way to go (for at least a few reasons).
I don't have a strong preference, but prepare_for_building should do
*something* with local_using_directives. I think it doesn't because
I was making so many changes I punted on this part. What's there
now leaves one wondering (e.g., why does buildsym_init initialize
local_using_directives? and why doesn't reset_symtab_globals reset
local_using_directives? and there are more.).
But I'm happy with leaving this for later,
I just wanted to point out the issue.
> gdb_assert (pending_macros == NULL);
> gdb_assert (pending_addrmap == NULL);
> gdb_assert (current_subfile == NULL);
> @@ -1179,6 +1187,7 @@ reset_symtab_globals (void)
> local_symbols = 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 +1290,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 +1647,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 +1750,7 @@ get_last_source_file (void)
> void
> buildsym_init (void)
> {
> - using_directives = NULL;
> + local_using_directives = NULL;
> subfile_stack = NULL;
>
> pending_addrmap_interesting = 0;
> @@ -1760,6 +1770,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);
> diff --git a/gdb/buildsym.h b/gdb/buildsym.h
> index f98203e..4c0ec15 100644
> --- a/gdb/buildsym.h
> +++ b/gdb/buildsym.h
> @@ -118,7 +118,11 @@ EXTERN struct pending *local_symbols;
>
> /* "using" directives local to lexical context. */
>
> -EXTERN struct using_direct *using_directives;
> +EXTERN struct using_direct *local_using_directives;
> +
> +/* global "using" directives. */
> +
> +EXTERN struct using_direct *global_using_directives;
>
> /* Stack representing unclosed lexical contexts (that will become
> blocks, eventually). */
> @@ -131,7 +135,7 @@ struct context_stack
>
> /* Pending using directives at the time we entered. */
>
> - struct using_direct *using_directives;
> + struct using_direct *local_using_directives;
>
> /* Pointer into blocklist as of entry */
>
> diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
> index 41f8d35..821ea9a 100644
> --- a/gdb/cp-namespace.c
> +++ b/gdb/cp-namespace.c
> @@ -91,7 +91,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *const symbol,
> anonymous namespace. So add symbols in it to the
> namespace given by the previous component if there is
> one, or to the global namespace if there isn't. */
> - cp_add_using_directive (dest, src, NULL, NULL, NULL, 1,
> + cp_add_using_directive (&local_using_directives,
> + dest, src, NULL, NULL, NULL, 1,
> &objfile->objfile_obstack);
> }
> /* The "+ 2" is for the "::". */
> @@ -103,7 +104,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *const symbol,
> }
> }
>
> -/* Add a using directive to using_directives. If the using directive
> +/* Add a using directive to USING_DIRECTIVES. If the using directive
> in question has already been added, don't add it twice.
>
> Create a new struct using_direct which imports the namespace SRC
> @@ -118,7 +119,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *const symbol,
> pointed to characters are not copied. */
>
> void
> -cp_add_using_directive (const char *dest,
> +cp_add_using_directive (struct using_direct **using_directives,
> + const char *dest,
> const char *src,
> const char *alias,
> const char *declaration,
> @@ -131,7 +133,7 @@ cp_add_using_directive (const char *dest,
>
> /* Has it already been added? */
>
> - for (current = using_directives; current != NULL; current = current->next)
> + for (current = *using_directives; current != NULL; current = current->next)
> {
> int ix;
> const char *param;
> @@ -195,8 +197,8 @@ cp_add_using_directive (const char *dest,
> VEC_length (const_char_ptr, excludes) * sizeof (*newobj->excludes));
> newobj->excludes[VEC_length (const_char_ptr, excludes)] = NULL;
>
> - newobj->next = using_directives;
> - using_directives = newobj;
> + newobj->next = *using_directives;
> + *using_directives = newobj;
> }
>
> /* Test whether or not NAMESPACE looks like it mentions an anonymous
> diff --git a/gdb/cp-support.h b/gdb/cp-support.h
> index e92d6e7..72e7aa5 100644
> --- a/gdb/cp-support.h
> +++ b/gdb/cp-support.h
> @@ -181,7 +181,8 @@ extern struct type *cp_lookup_rtti_type (const char *name,
>
> extern int cp_is_in_anonymous (const char *symbol_name);
>
> -extern void cp_add_using_directive (const char *dest,
> +extern void cp_add_using_directive (struct using_direct **using_directives,
> + const char *dest,
> const char *src,
> const char *alias,
> const char *declaration,
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index f440956..370f66b 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -8875,6 +8875,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
> const char *import_prefix;
> VEC (const_char_ptr) *excludes = NULL;
> struct cleanup *cleanups;
> + struct using_direct **using_directives;
>
> import_attr = dwarf2_attr (die, DW_AT_import, cu);
> if (import_attr == NULL)
> @@ -8994,10 +8995,20 @@ 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,
> + /* 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. */
> + if (cu->language == language_ada && context_stack_depth == 0)
> + using_directives = &global_using_directives;
> + else
> + using_directives = &local_using_directives;
> + cp_add_using_directive (using_directives,
> + import_prefix,
> + canonical_name,
> + import_alias,
> + imported_declaration,
> excludes,
> 0,
> &objfile->objfile_obstack);
> @@ -11480,7 +11491,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. */
> @@ -11526,7 +11537,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,
> @@ -11545,7 +11556,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. */
> @@ -14094,7 +14105,10 @@ 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,
> + cp_add_using_directive ((context_stack_depth > 0)
> + ? &local_using_directives
> + : &global_using_directives,
====
Indentation is wrong.
Typically what we do is surround the entire argument in () and indent
like so:
(foo > 0
? bar
: baz),
Plus this needs a language_ada check (right?).
> + previous_prefix, TYPE_NAME (type), NULL,
> NULL, NULL, 0, &objfile->objfile_obstack);
> }
> }
> diff --git a/gdb/testsuite/gdb.ada/fun_renaming.exp b/gdb/testsuite/gdb.ada/fun_renaming.exp
> new file mode 100644
> index 0000000..fa76171
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/fun_renaming.exp
> @@ -0,0 +1,83 @@
> +# Copyright 2015 Free Software Foundation, Inc.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +load_lib "ada.exp"
> +
> +standard_ada_testfile fun_renaming
> +
> +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
> + return -1
> +}
> +
> +clean_restart ${testfile}
> +
> +set bp_location [gdb_get_line_number "BREAK" ${testdir}/fun_renaming.adb]
> +runto "fun_renaming.adb:$bp_location"
> +
> +# Sanity check: make sure we can call a regular global function.
> +gdb_test "print next(1)" " = 2"
> +
> +# Starting with GCC 6, renamed subprograms are materialized in the debugging
> +# information: make sure we can call the regular global function using its
> +# multiple names.
> +
> +set test "print n(1)"
> +gdb_test_multiple $test $test {
> + -re " = 2\..*$gdb_prompt $" {
> + pass $test
> + }
> + -re "No definition of \"n\" in current context\..*$gdb_prompt $" {
> + if {[test_compiler_info {gcc-6*}]} {
> + fail $test
> + } else {
> + xfail $test
> + }
> + }
> +
> +}
> +set test "print renamed_next(1)"
> +gdb_test_multiple $test $test {
> + -re " = 2\..*$gdb_prompt $" {
> + pass $test
> + }
> + -re "No definition of \"renamed_next\" in current context\..*$gdb_prompt $" {
> + if {[test_compiler_info {gcc-6*}]} {
> + fail $test
> + } else {
> + xfail $test
> + }
> + }
> +}
> +
> +set test "print pack.renamed_next(1)"
> +gdb_test_multiple $test $test {
> + -re " = 2\..*$gdb_prompt $" {
> + pass $test
> + }
> + -re "No definition of \"pack\.renamed_next\" in current context\..*$gdb_prompt $" {
> + if {[test_compiler_info {gcc-6*}]} {
> + fail $test
> + } else {
> + xfail $test
> + }
> + }
> + -re "Type <data variable, no debug info> is not a structure or union type\..*$gdb_prompt $" {
> + if {[test_compiler_info {gcc-6*}]} {
> + fail $test
> + } else {
> + xfail $test
> + }
> + }
> +}
> diff --git a/gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb b/gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb
> new file mode 100644
> index 0000000..c933585
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb
> @@ -0,0 +1,23 @@
> +-- Copyright 2015 Free Software Foundation, Inc.
> +--
> +-- This program is free software; you can redistribute it and/or modify
> +-- it under the terms of the GNU General Public License as published by
> +-- the Free Software Foundation; either version 3 of the License, or
> +-- (at your option) any later version.
> +--
> +-- This program is distributed in the hope that it will be useful,
> +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
> +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +-- GNU General Public License for more details.
> +--
> +-- You should have received a copy of the GNU General Public License
> +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +with Pack;
> +
> +procedure Fun_Renaming is
> + function N (I : Integer) return Integer renames Pack.Next;
> +begin
> + Pack.Discard (N (1)); -- BREAK
> + Pack.Discard (Pack.Renamed_Next (1)); -- BREAK
> +end Fun_Renaming;
> diff --git a/gdb/testsuite/gdb.ada/fun_renaming/pack.adb b/gdb/testsuite/gdb.ada/fun_renaming/pack.adb
> new file mode 100644
> index 0000000..bdcd432
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/fun_renaming/pack.adb
> @@ -0,0 +1,26 @@
> +-- Copyright 2015 Free Software Foundation, Inc.
> +--
> +-- This program is free software; you can redistribute it and/or modify
> +-- it under the terms of the GNU General Public License as published by
> +-- the Free Software Foundation; either version 3 of the License, or
> +-- (at your option) any later version.
> +--
> +-- This program is distributed in the hope that it will be useful,
> +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
> +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +-- GNU General Public License for more details.
> +--
> +-- You should have received a copy of the GNU General Public License
> +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +package body Pack is
> + function Next (I : Integer) return Integer is
> + begin
> + return I + 1;
> + end Next;
> +
> + procedure Discard (I : Integer) is
> + begin
> + null;
> + end Discard;
> +end Pack;
> diff --git a/gdb/testsuite/gdb.ada/fun_renaming/pack.ads b/gdb/testsuite/gdb.ada/fun_renaming/pack.ads
> new file mode 100644
> index 0000000..2cf722c
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/fun_renaming/pack.ads
> @@ -0,0 +1,22 @@
> +-- Copyright 2015 Free Software Foundation, Inc.
> +--
> +-- This program is free software; you can redistribute it and/or modify
> +-- it under the terms of the GNU General Public License as published by
> +-- the Free Software Foundation; either version 3 of the License, or
> +-- (at your option) any later version.
> +--
> +-- This program is distributed in the hope that it will be useful,
> +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
> +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +-- GNU General Public License for more details.
> +--
> +-- You should have received a copy of the GNU General Public License
> +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +package Pack is
> +
> + function Next (I : Integer) return Integer;
> + function Renamed_Next (I : Integer) return Integer renames Next;
> + procedure Discard (I : Integer);
> +
> +end Pack;