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 1/2] namespace support


Ops. The patch in the previous message was missing the test case.
Here is the same patch with the test case included:


2009-05-21 Sami Wagiaalla <swagiaal@redhat.com>


       * dwarf2read.c (process_die): Handle import statements
       (DW_TAG_imported_declaration, case DW_TAG_imported_module)
       (read_import_statement): New.
       (read_func_scope): Update using_directives to point to current context
       (read_lexical_block_scope): Ditto.
       * cp-support.h: Added prototype for cp_add_using.
       * cp-namespace.c: Removed local context_stack.
       (cp_initialize_namespace): Deleted.
       (cp_finalize_namespace): Deleted.
       (cp_add_using_directive): Use using_directives instead of using_list.
       (cp_add_using): No longer static.
       * buildsym.h: Created global using_direct variable.
       Created using_direct variable in context_stack.
       * buildsym.c (finish_block): Set using directives for the block	under
       construction.
       (start_symtab): Removed call to cp_initialize_namespace().
       (end_symtab): Removed call to cp_finalize_namespace().
       (push_context): Save and reset using_directives.
       * block.c (block_using): Return using directives for given
       block instead of static block.

diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..9ebe975 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -206,25 +206,16 @@ block_set_scope (struct block *block, const char *scope,
   BLOCK_NAMESPACE (block)->scope = scope;
 }

-/* This returns the first using directives associated to BLOCK, if
+/* This returns the using directives list associated with BLOCK, if
    any.  */

-/* FIXME: carlton/2003-04-23: This uses the fact that we currently
-   only have using directives in static blocks, because we only
-   generate using directives from anonymous namespaces.  Eventually,
-   when we support using directives everywhere, we'll want to replace
-   this by some iterator functions.  */
-
 struct using_direct *
 block_using (const struct block *block)
 {
-  const struct block *static_block = block_static_block (block);
-
-  if (static_block == NULL
-      || BLOCK_NAMESPACE (static_block) == NULL)
+  if (block == NULL || BLOCK_NAMESPACE (block) == NULL)
     return NULL;
   else
-    return BLOCK_NAMESPACE (static_block)->using;
+    return BLOCK_NAMESPACE (block)->using;
 }

 /* Set BLOCK's using member to USING; if needed, allocate memory via
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index e7c48fe..e6ef9c6 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -384,6 +384,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       opblock = pblock;
     }

+  block_set_using (block, using_directives, &objfile->objfile_obstack);
+
   record_pending_block (objfile, block, opblock);

   return block;
@@ -812,10 +814,6 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
   /* We shouldn't have any address map at this point.  */
   gdb_assert (! pending_addrmap);

-  /* Set up support for C++ namespace support, in case we need it.  */
-
-  cp_initialize_namespace ();
-
   /* Initialize the list of sub source files with one entry for this
      file (the top-level source file).  */

@@ -1012,8 +1010,6 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
 		    objfile);
       blockvector = make_blockvector (objfile);
-      cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
-			     &objfile->objfile_obstack);
     }

   /* Read the line table if it has to be read separately.  */
@@ -1225,10 +1221,12 @@ push_context (int desc, CORE_ADDR valu)
   new->params = param_symbols;
   new->old_blocks = pending_blocks;
   new->start_addr = valu;
+  new->using_directives = using_directives;
   new->name = NULL;

   local_symbols = NULL;
   param_symbols = NULL;
+  using_directives = NULL;

   return new;
 }
diff --git a/gdb/buildsym.h b/gdb/buildsym.h
index bf23ecc..6f8b09f 100644
--- a/gdb/buildsym.h
+++ b/gdb/buildsym.h
@@ -125,6 +125,10 @@ EXTERN struct pending *local_symbols;

EXTERN struct pending *param_symbols;

+/* "using" directives local to lexical context.  */
+
+EXTERN struct using_direct *using_directives;
+
 /* Stack representing unclosed lexical contexts (that will become
    blocks, eventually).  */

@@ -138,6 +142,10 @@ struct context_stack

struct pending *params;

+    /* Pending using directives at the time we entered.  */
+
+    struct using_direct *using_directives;
+
     /* Pointer into blocklist as of entry */

     struct pending_block *old_blocks;
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index c6c5617..f3b2194 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -30,15 +30,7 @@
 #include "dictionary.h"
 #include "command.h"
 #include "frame.h"
-
-/* List of using directives that are active in the current file.  */
-
-static struct using_direct *using_list;
-
-static struct using_direct *cp_add_using (const char *name,
-					  unsigned int inner_len,
-					  unsigned int outer_len,
-					  struct using_direct *next);
+#include "buildsym.h"

 static struct using_direct *cp_copy_usings (struct using_direct *using,
 					    struct obstack *obstack);
@@ -78,31 +70,6 @@ static struct symbol *lookup_possible_namespace_symbol (const char *name);

static void maintenance_cplus_namespace (char *args, int from_tty);

-/* Set up support for dealing with C++ namespace info in the current
-   symtab.  */
-
-void cp_initialize_namespace ()
-{
-  using_list = NULL;
-}
-
-/* Add all the using directives we've gathered to the current symtab.
-   STATIC_BLOCK should be the symtab's static block; OBSTACK is used
-   for allocation.  */
-
-void
-cp_finalize_namespace (struct block *static_block,
-		       struct obstack *obstack)
-{
-  if (using_list != NULL)
-    {
-      block_set_using (static_block,
-		       cp_copy_usings (using_list, obstack),
-		       obstack);
-      using_list = NULL;
-    }
-}
-
 /* Check to see if SYMBOL refers to an object contained within an
    anonymous namespace; if so, add an appropriate using directive.  */

@@ -170,7 +137,7 @@ cp_add_using_directive (const char *name, unsigned int outer_length,

/* Has it already been added? */

-  for (current = using_list; current != NULL; current = current->next)
+  for (current = using_directives; current != NULL; current = current->next)
     {
       if ((strncmp (current->inner, name, inner_length) == 0)
 	  && (strlen (current->inner) == inner_length)
@@ -178,8 +145,8 @@ cp_add_using_directive (const char *name, unsigned int outer_length,
 	return;
     }

-  using_list = cp_add_using (name, inner_length, outer_length,
-			     using_list);
+  using_directives = cp_add_using (name, inner_length, outer_length,
+                                   using_directives);
 }

 /* Record the namespace that the function defined by SYMBOL was
@@ -237,7 +204,7 @@ cp_is_anonymous (const char *namespace)
    using xmalloc.  It copies the strings, so NAME can be a temporary
    string.  */

-static struct using_direct *
+struct using_direct *
 cp_add_using (const char *name,
 	      unsigned int inner_len,
 	      unsigned int outer_len,
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 837ca6c..e577f7d 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -80,6 +80,11 @@ extern void cp_add_using_directive (const char *name,
 				    unsigned int outer_length,
 				    unsigned int inner_length);

+extern struct using_direct *cp_add_using (const char *name,
+					  unsigned int inner_len,
+					  unsigned int outer_len,
+					  struct using_direct *next);
+
 extern void cp_initialize_namespace (void);

 extern void cp_finalize_namespace (struct block *static_block,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ae8870c..6569798 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -946,6 +946,8 @@ static void read_namespace (struct die_info *die, struct dwarf2_cu *);

static void read_module (struct die_info *die, struct dwarf2_cu *cu);

+static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
+
 static const char *namespace_name (struct die_info *die,
 				   int *is_anonymous, struct dwarf2_cu *);

@@ -2984,14 +2986,12 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
-      /* FIXME: carlton/2002-10-16: Eventually, we should use the
-	 information contained in these.  DW_TAG_imported_declaration
-	 dies shouldn't have children; DW_TAG_imported_module dies
-	 shouldn't in the C++ case, but conceivably could in the
-	 Fortran case.  */
       processing_has_namespace_info = 1;
-      complaint (&symfile_complaints, _("unsupported tag: '%s'"),
-		 dwarf_tag_name (die->tag));
+      if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
+				 || cu->language != language_fortran))
+	complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
+		   dwarf_tag_name (die->tag));
+      read_import_statement (die, cu);
       break;
     default:
       new_symbol (die, NULL, cu);
@@ -3037,6 +3037,69 @@ dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
   return name;
 }

+/* Read the import statement specified by the given die and record it.  */
+
+static void
+read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *import_attr;
+  struct die_info *imported_die;
+  const char *imported_name;
+  int is_anonymous = 0;
+
+  import_attr = dwarf2_attr (die, DW_AT_import, cu);
+  if (import_attr == NULL)
+    {
+      complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+		 dwarf_tag_name (die->tag));
+      return;
+    }
+
+  imported_die = follow_die_ref (die, import_attr, &cu);
+  imported_name = dwarf2_name (imported_die, cu);
+  if (imported_name == NULL)
+    {
+      /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
+
+        The import in the following code:
+        namespace A
+          {
+            typedef int B;
+          }
+
+        int main ()
+          {
+            using A::B;
+            B b;
+            return b;
+          }
+
+        ...
+         <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration)
+            <52>   DW_AT_decl_file   : 1
+            <53>   DW_AT_decl_line   : 6
+            <54>   DW_AT_import      : <0x75>
+         <2><58>: Abbrev Number: 4 (DW_TAG_typedef)
+            <59>   DW_AT_name        : B
+            <5b>   DW_AT_decl_file   : 1
+            <5c>   DW_AT_decl_line   : 2
+            <5d>   DW_AT_type        : <0x6e>
+        ...
+         <1><75>: Abbrev Number: 7 (DW_TAG_base_type)
+            <76>   DW_AT_byte_size   : 4
+            <77>   DW_AT_encoding    : 5        (signed)
+
+        imports the wrong die ( 0x75 instead of 0x58 ).
+        This case will be ignored until the gcc bug is fixed.  */
+      return;
+    }
+
+  /* FIXME: dwarf2_name (die); for the local name after import.  */
+
+  using_directives = cp_add_using (imported_name, strlen (imported_name), 0,
+                                   using_directives);
+}
+
 static void
 initialize_cu_func_list (struct dwarf2_cu *cu)
 {
@@ -3370,6 +3433,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
      back to building a containing block's symbol lists.  */
   local_symbols = new->locals;
   param_symbols = new->params;
+  using_directives = new->using_directives;

   /* If we've finished processing a top-level function, subsequent
      symbols go in the file symbol list.  */
@@ -3432,6 +3496,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
       dwarf2_record_block_ranges (die, block, baseaddr, cu);
     }
   local_symbols = new->locals;
+  using_directives = new->using_directives;
 }

 /* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
diff --git a/gdb/testsuite/gdb.cp/namespace-using.cc b/gdb/testsuite/gdb.cp/namespace-using.cc
new file mode 100644
index 0000000..4786fd5
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-using.cc
@@ -0,0 +1,45 @@
+namespace A
+{
+  int _a = 1;
+  int x = 2;
+}
+
+int marker4(){
+	using A::x;
+	return 0;
+}
+
+int marker3(){
+	return marker4();
+}
+
+int marker2()
+{
+  namespace B = A;
+  B::_a;
+  return marker3();
+}
+
+int marker1()
+{
+  int total = 0;
+  {
+    int b = 1;
+    {
+      using namespace A;
+      int c = 2;
+      {
+        int d = 3;
+        total = _a + b + c + d + marker2(); // marker1 stop
+      }
+    }
+  }
+  return total;
+}
+
+int main()
+{
+  using namespace A;
+  _a;
+  return marker1();
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-using.exp b/gdb/testsuite/gdb.cp/namespace-using.exp
new file mode 100644
index 0000000..f24973f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-using.exp
@@ -0,0 +1,87 @@
+# Copyright 2008 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/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-using
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+# test printing of namespace imported within
+# the function.
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_test "print _a" "= 1"
+
+############################################
+# test printing of namespace imported into
+# a scope containing the pc.
+
+gdb_breakpoint [gdb_get_line_number "marker1 stop"]
+gdb_continue_to_breakpoint "marker1 stop"
+
+gdb_test "print _a" "= 1" "print _a in a nested scope"
+
+############################################
+# Test printing of namespace aliases
+
+setup_kfail "gdb/7935" "*-*-*"
+if ![runto marker2] then {
+    perror "couldn't run to breakpoint marker2"
+    continue
+}
+
+gdb_test "print B::a" "= 1"
+
+############################################
+# Test that names are not printed when they
+# are not imported
+
+gdb_breakpoint "marker3"
+gdb_continue_to_breakpoint "marker3"
+
+gdb_test "print _a" "No symbol \"_a\" in current context." "Print a without import"
+
+############################################
+# Test printing of individually imported elements
+
+setup_kfail "gdb/7936" "*-*-*"
+if ![runto marker4] then {
+    perror "couldn't run to breakpoint marker4"
+    continue
+}
+
+gdb_test "print x" "= 2"
    
    2009-05-21  Sami Wagiaalla  <swagiaal@redhat.com>
    
       * dwarf2read.c (process_die): Handle import statements
       (DW_TAG_imported_declaration, case DW_TAG_imported_module)
       (read_import_statement): New.
       (read_func_scope): Update using_directives to point to current context
       (read_lexical_block_scope): Ditto.
       * cp-support.h: Added prototype for cp_add_using.
       * cp-namespace.c: Removed local context_stack.
       (cp_initialize_namespace): Deleted.
       (cp_finalize_namespace): Deleted.
       (cp_add_using_directive): Use using_directives instead of using_list.
       (cp_add_using): No longer static.
       * buildsym.h: Created global using_direct variable.
       Created using_direct variable in context_stack.
       * buildsym.c (finish_block): Set using directives for the block	under
       construction.
       (start_symtab): Removed call to cp_initialize_namespace().
       (end_symtab): Removed call to cp_finalize_namespace().
       (push_context): Save and reset using_directives.
       * block.c (block_using): Return using directives for given
       block instead of static block.

diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..9ebe975 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -206,25 +206,16 @@ block_set_scope (struct block *block, const char *scope,
   BLOCK_NAMESPACE (block)->scope = scope;
 }
 
-/* This returns the first using directives associated to BLOCK, if
+/* This returns the using directives list associated with BLOCK, if
    any.  */
 
-/* FIXME: carlton/2003-04-23: This uses the fact that we currently
-   only have using directives in static blocks, because we only
-   generate using directives from anonymous namespaces.  Eventually,
-   when we support using directives everywhere, we'll want to replace
-   this by some iterator functions.  */
-
 struct using_direct *
 block_using (const struct block *block)
 {
-  const struct block *static_block = block_static_block (block);
-
-  if (static_block == NULL
-      || BLOCK_NAMESPACE (static_block) == NULL)
+  if (block == NULL || BLOCK_NAMESPACE (block) == NULL)
     return NULL;
   else
-    return BLOCK_NAMESPACE (static_block)->using;
+    return BLOCK_NAMESPACE (block)->using;
 }
 
 /* Set BLOCK's using member to USING; if needed, allocate memory via
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index e7c48fe..e6ef9c6 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -384,6 +384,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       opblock = pblock;
     }
 
+  block_set_using (block, using_directives, &objfile->objfile_obstack);
+
   record_pending_block (objfile, block, opblock);
 
   return block;
@@ -812,10 +814,6 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
   /* We shouldn't have any address map at this point.  */
   gdb_assert (! pending_addrmap);
 
-  /* Set up support for C++ namespace support, in case we need it.  */
-
-  cp_initialize_namespace ();
-
   /* Initialize the list of sub source files with one entry for this
      file (the top-level source file).  */
 
@@ -1012,8 +1010,6 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
 		    objfile);
       blockvector = make_blockvector (objfile);
-      cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
-			     &objfile->objfile_obstack);
     }
 
   /* Read the line table if it has to be read separately.  */
@@ -1225,10 +1221,12 @@ push_context (int desc, CORE_ADDR valu)
   new->params = param_symbols;
   new->old_blocks = pending_blocks;
   new->start_addr = valu;
+  new->using_directives = using_directives;
   new->name = NULL;
 
   local_symbols = NULL;
   param_symbols = NULL;
+  using_directives = NULL;
 
   return new;
 }
diff --git a/gdb/buildsym.h b/gdb/buildsym.h
index bf23ecc..6f8b09f 100644
--- a/gdb/buildsym.h
+++ b/gdb/buildsym.h
@@ -125,6 +125,10 @@ EXTERN struct pending *local_symbols;
 
 EXTERN struct pending *param_symbols;
 
+/* "using" directives local to lexical context.  */
+
+EXTERN struct using_direct *using_directives;
+
 /* Stack representing unclosed lexical contexts (that will become
    blocks, eventually).  */
 
@@ -138,6 +142,10 @@ struct context_stack
 
     struct pending *params;
 
+    /* Pending using directives at the time we entered.  */
+
+    struct using_direct *using_directives;
+
     /* Pointer into blocklist as of entry */
 
     struct pending_block *old_blocks;
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index c6c5617..f3b2194 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -30,15 +30,7 @@
 #include "dictionary.h"
 #include "command.h"
 #include "frame.h"
-
-/* List of using directives that are active in the current file.  */
-
-static struct using_direct *using_list;
-
-static struct using_direct *cp_add_using (const char *name,
-					  unsigned int inner_len,
-					  unsigned int outer_len,
-					  struct using_direct *next);
+#include "buildsym.h"
 
 static struct using_direct *cp_copy_usings (struct using_direct *using,
 					    struct obstack *obstack);
@@ -78,31 +70,6 @@ static struct symbol *lookup_possible_namespace_symbol (const char *name);
 
 static void maintenance_cplus_namespace (char *args, int from_tty);
 
-/* Set up support for dealing with C++ namespace info in the current
-   symtab.  */
-
-void cp_initialize_namespace ()
-{
-  using_list = NULL;
-}
-
-/* Add all the using directives we've gathered to the current symtab.
-   STATIC_BLOCK should be the symtab's static block; OBSTACK is used
-   for allocation.  */
-
-void
-cp_finalize_namespace (struct block *static_block,
-		       struct obstack *obstack)
-{
-  if (using_list != NULL)
-    {
-      block_set_using (static_block,
-		       cp_copy_usings (using_list, obstack),
-		       obstack);
-      using_list = NULL;
-    }
-}
-
 /* Check to see if SYMBOL refers to an object contained within an
    anonymous namespace; if so, add an appropriate using directive.  */
 
@@ -170,7 +137,7 @@ cp_add_using_directive (const char *name, unsigned int outer_length,
 
   /* Has it already been added?  */
 
-  for (current = using_list; current != NULL; current = current->next)
+  for (current = using_directives; current != NULL; current = current->next)
     {
       if ((strncmp (current->inner, name, inner_length) == 0)
 	  && (strlen (current->inner) == inner_length)
@@ -178,8 +145,8 @@ cp_add_using_directive (const char *name, unsigned int outer_length,
 	return;
     }
 
-  using_list = cp_add_using (name, inner_length, outer_length,
-			     using_list);
+  using_directives = cp_add_using (name, inner_length, outer_length,
+                                   using_directives);
 }
 
 /* Record the namespace that the function defined by SYMBOL was
@@ -237,7 +204,7 @@ cp_is_anonymous (const char *namespace)
    using xmalloc.  It copies the strings, so NAME can be a temporary
    string.  */
 
-static struct using_direct *
+struct using_direct *
 cp_add_using (const char *name,
 	      unsigned int inner_len,
 	      unsigned int outer_len,
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 837ca6c..e577f7d 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -80,6 +80,11 @@ extern void cp_add_using_directive (const char *name,
 				    unsigned int outer_length,
 				    unsigned int inner_length);
 
+extern struct using_direct *cp_add_using (const char *name,
+					  unsigned int inner_len,
+					  unsigned int outer_len,
+					  struct using_direct *next);
+
 extern void cp_initialize_namespace (void);
 
 extern void cp_finalize_namespace (struct block *static_block,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ae8870c..6569798 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -946,6 +946,8 @@ static void read_namespace (struct die_info *die, struct dwarf2_cu *);
 
 static void read_module (struct die_info *die, struct dwarf2_cu *cu);
 
+static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
+
 static const char *namespace_name (struct die_info *die,
 				   int *is_anonymous, struct dwarf2_cu *);
 
@@ -2984,14 +2986,12 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
       break;
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
-      /* FIXME: carlton/2002-10-16: Eventually, we should use the
-	 information contained in these.  DW_TAG_imported_declaration
-	 dies shouldn't have children; DW_TAG_imported_module dies
-	 shouldn't in the C++ case, but conceivably could in the
-	 Fortran case.  */
       processing_has_namespace_info = 1;
-      complaint (&symfile_complaints, _("unsupported tag: '%s'"),
-		 dwarf_tag_name (die->tag));
+      if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
+				 || cu->language != language_fortran))
+	complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
+		   dwarf_tag_name (die->tag));
+      read_import_statement (die, cu);
       break;
     default:
       new_symbol (die, NULL, cu);
@@ -3037,6 +3037,69 @@ dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
   return name;
 }
 
+/* Read the import statement specified by the given die and record it.  */
+
+static void
+read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *import_attr;
+  struct die_info *imported_die;
+  const char *imported_name;
+  int is_anonymous = 0;
+
+  import_attr = dwarf2_attr (die, DW_AT_import, cu);
+  if (import_attr == NULL)
+    {
+      complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+		 dwarf_tag_name (die->tag));
+      return;
+    }
+
+  imported_die = follow_die_ref (die, import_attr, &cu);
+  imported_name = dwarf2_name (imported_die, cu);
+  if (imported_name == NULL)
+    {
+      /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
+
+        The import in the following code:
+        namespace A
+          {
+            typedef int B;
+          }
+
+        int main ()
+          {
+            using A::B;
+            B b;
+            return b;
+          }
+
+        ...
+         <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration)
+            <52>   DW_AT_decl_file   : 1
+            <53>   DW_AT_decl_line   : 6
+            <54>   DW_AT_import      : <0x75>
+         <2><58>: Abbrev Number: 4 (DW_TAG_typedef)
+            <59>   DW_AT_name        : B
+            <5b>   DW_AT_decl_file   : 1
+            <5c>   DW_AT_decl_line   : 2
+            <5d>   DW_AT_type        : <0x6e>
+        ...
+         <1><75>: Abbrev Number: 7 (DW_TAG_base_type)
+            <76>   DW_AT_byte_size   : 4
+            <77>   DW_AT_encoding    : 5        (signed)
+
+        imports the wrong die ( 0x75 instead of 0x58 ).
+        This case will be ignored until the gcc bug is fixed.  */
+      return;
+    }
+
+  /* FIXME: dwarf2_name (die); for the local name after import.  */
+
+  using_directives = cp_add_using (imported_name, strlen (imported_name), 0,
+                                   using_directives);
+}
+
 static void
 initialize_cu_func_list (struct dwarf2_cu *cu)
 {
@@ -3370,6 +3433,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
      back to building a containing block's symbol lists.  */
   local_symbols = new->locals;
   param_symbols = new->params;
+  using_directives = new->using_directives;
 
   /* If we've finished processing a top-level function, subsequent
      symbols go in the file symbol list.  */
@@ -3432,6 +3496,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
       dwarf2_record_block_ranges (die, block, baseaddr, cu);
     }
   local_symbols = new->locals;
+  using_directives = new->using_directives;
 }
 
 /* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
diff --git a/gdb/testsuite/gdb.cp/namespace-using.cc b/gdb/testsuite/gdb.cp/namespace-using.cc
new file mode 100644
index 0000000..4786fd5
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-using.cc
@@ -0,0 +1,45 @@
+namespace A
+{
+  int _a = 1;
+  int x = 2;
+}
+
+int marker4(){
+	using A::x;
+	return 0;
+}
+
+int marker3(){
+	return marker4();
+}
+
+int marker2()
+{
+  namespace B = A;
+  B::_a;
+  return marker3();
+}
+
+int marker1()
+{
+  int total = 0;
+  {
+    int b = 1;
+    {
+      using namespace A;
+      int c = 2;
+      {
+        int d = 3;
+        total = _a + b + c + d + marker2(); // marker1 stop
+      }
+    }
+  }
+  return total;
+}
+
+int main()
+{
+  using namespace A;
+  _a;
+  return marker1();
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-using.exp b/gdb/testsuite/gdb.cp/namespace-using.exp
new file mode 100644
index 0000000..f24973f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-using.exp
@@ -0,0 +1,87 @@
+# Copyright 2008 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/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-using
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+# test printing of namespace imported within
+# the function.
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_test "print _a" "= 1"
+
+############################################
+# test printing of namespace imported into 
+# a scope containing the pc.
+
+gdb_breakpoint [gdb_get_line_number "marker1 stop"]
+gdb_continue_to_breakpoint "marker1 stop"
+
+gdb_test "print _a" "= 1" "print _a in a nested scope"
+
+############################################
+# Test printing of namespace aliases
+
+setup_kfail "gdb/7935" "*-*-*"
+if ![runto marker2] then {
+    perror "couldn't run to breakpoint marker2"
+    continue
+}
+
+gdb_test "print B::a" "= 1"
+
+############################################
+# Test that names are not printed when they 
+# are not imported
+
+gdb_breakpoint "marker3"
+gdb_continue_to_breakpoint "marker3"
+
+gdb_test "print _a" "No symbol \"_a\" in current context." "Print a without import"
+
+############################################
+# Test printing of individually imported elements
+
+setup_kfail "gdb/7936" "*-*-*"
+if ![runto marker4] then {
+    perror "couldn't run to breakpoint marker4"
+    continue
+}
+
+gdb_test "print x" "= 2"

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