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]

[PATCH] [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 cp-support.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.
	* 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.
	(cp_scan_for_anonymous_namespaces): Update call to
	cp_add_using_directive.
	* 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>.
---
 gdb/ada-lang.c                                     | 199 +++++++++++++++------
 gdb/buildsym.c                                     |  23 ++-
 gdb/buildsym.h                                     |   8 +-
 gdb/cp-namespace.c                                 |  14 +-
 gdb/cp-support.h                                   |   3 +-
 gdb/dwarf2read.c                                   |  30 +++-
 gdb/testsuite/gdb.ada/fun_renaming.exp             |  83 +++++++++
 .../gdb.ada/fun_renaming/fun_renaming.adb          |  23 +++
 gdb/testsuite/gdb.ada/fun_renaming/pack.adb        |  26 +++
 gdb/testsuite/gdb.ada/fun_renaming/pack.ads        |  22 +++
 10 files changed, 356 insertions(+), 75 deletions(-)
 create mode 100644 gdb/testsuite/gdb.ada/fun_renaming.exp
 create mode 100644 gdb/testsuite/gdb.ada/fun_renaming/fun_renaming.adb
 create mode 100644 gdb/testsuite/gdb.ada/fun_renaming/pack.adb
 create mode 100644 gdb/testsuite/gdb.ada/fun_renaming/pack.ads

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);
   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,
+				  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;
-- 
2.4.6


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