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


Ping

Sami Wagiaalla wrote:

Currently imports statements are stored in the nearest static block. Also, these import statements only correspond to the implicit importing of annonymous namespaces.

This patch enables each block to own its own 'using
directives', and creates using directives for non anonymous
imports.



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cf44f2a..4614659 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,26 @@
+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.
+
2009-05-19 Jan Kratochvil <jan.kratochvil@redhat.com>


Remove the PROT parameter from openp.
diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..da36f7c 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -206,25 +206,17 @@ block_set_scope (struct block *block, const char *scope,
BLOCK_NAMESPACE (block)->scope = scope;
}


-/* This returns the first using directives associated to 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.  */
+/* This returns the using directives list associated to BLOCK, if
+   any.  Each BLOCK_NAMESPACE()->USING already contains all the namespaces
+   imported at that code point - even those from its parent blocks.  */

 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 6de817f..8c4f53b 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;
@@ -815,10 +817,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).  */

@@ -1015,8 +1013,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.  */
@@ -1228,10 +1224,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..f542aca 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..8bb341f 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 6ddaecd..dd7cf67 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -971,6 +971,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 *);


@@ -2880,14 +2882,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);
@@ -2933,6 +2933,38 @@ 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 = namespace_name (imported_die, &is_anonymous, cu);
+ if (imported_name == NULL)
+ {
+ /* C++ imports from std:: DW_TAG_base_type with no DW_AT_name - why? */
+ 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)
{
@@ -3266,6 +3298,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. */
@@ -3328,6 +3361,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/ChangeLog b/gdb/testsuite/ChangeLog
index 70ded08..4b34527 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-05-21 Sami Wagiaalla <swagiaal@redhat.com>
+
+ * gdb.cp/namespace-using.exp: New test.
+ * gdb.cp/namespace-using.cc: New test program.
+
2009-05-18 Jon Beniston <jon@beniston.com>


* gdb.asm/asm-source.exp: Add lm32 target.
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..2e57927
--- /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
+
+send_gdb "break marker3\n"
+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 marker2"
+ 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]