This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [Ada] Add support for subprogram renamings


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]