This is the mail archive of the gdb-patches@sources.redhat.com 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]

[rfa] namespace scope, take 2


Here's a new version of my namespace scope patch, using the language
hook that I just posted an RFA for.  Assuming that's okay, then is
this okay, Daniel?  I know you said that it was fine a few weeks ago,
but I wanted to give you another chance to complain since it's going
in a file you maintain. :-)  (Except for a few functions in block.c,
but Elena already said those were okay.  Well, block_global_block is
new to this version of the patch, but I'm sure it's
non-controversial.)  I added the extra test to namespace.exp that you
requested.

Tested on GCC 3.2, DWARF 2, i686-pc-linux-gnu; no regressions, and all
new tests pass.  Probably some of the new anonymous namespace tests
will fail with GCC 2.95.3, becuase of a stupid difference between the
output of the v2 and v3 demanglers, but I'm not going to worry about
that for now, given the poor quality of namespace support in GCC
2.95.3.  If that really bothers anybody, I can look into in in a
subsequent patch.

David Carlton
carlton@bactrian.org

2003-05-18  David Carlton  <carlton@bactrian.org>

	Partial fix for PR c++/827.
	* cp-support.h: Include symtab.h.
	Declare cp_lookup_symbol_nonlocal, cp_lookup_symbol_namespace.
	* cp-namespace.c: Update contributors.
	(cp_lookup_symbol_nonlocal): New.
	(lookup_namespace_scope, cp_lookup_symbol_namespace)
	(lookup_symbol_file): Ditto.
	* c-lang.c (cplus_language_defn): Use cp_lookup_symbol_nonlocal.
	* block.h: Declare block_scope, block_using, block_global_block.
	* block.c (block_scope): New.
	(block_using, block_global_block): Ditto.
	* Makefile.in (cp_support_h): Depend on symtab_h.
	* config/djgpp/fnchange.lst: Add testsuite/gdb.c++/namespace1.cc.

2003-05-18  David Carlton  <carlton@bactrian.org>

	* gdb.c++/namespace.exp: Add namespace scope and anonymous
	namespace tests.
	Bump copyright date.
	* gdb.c++/namespace.cc: Add anonymous namespace and namespace C.
	(main): Call C::D::marker2.
	* gdb.c++/namespace1.cc: New file.

Index: cp-namespace.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-namespace.c,v
retrieving revision 1.1
diff -u -p -r1.1 cp-namespace.c
--- cp-namespace.c	15 Apr 2003 23:07:11 -0000	1.1
+++ cp-namespace.c	18 May 2003 17:32:51 -0000
@@ -1,7 +1,7 @@
 /* Helper routines for C++ support in GDB.
    Copyright 2003 Free Software Foundation, Inc.
 
-   Contributed by David Carlton.
+   Contributed by David Carlton and by Kealia, Inc.
 
    This file is part of GDB.
 
@@ -52,6 +52,21 @@ static struct using_direct *cp_add_using
 static struct using_direct *cp_copy_usings (struct using_direct *using,
 					    struct obstack *obstack);
 
+static struct symbol *lookup_namespace_scope (const char *name,
+					      const char *linkage_name,
+					      const struct block *block,
+					      const domain_enum domain,
+					      struct symtab **symtab,
+					      const char *scope,
+					      int scope_len);
+
+static struct symbol *lookup_symbol_file (const char *name,
+					  const char *linkage_name,
+					  const struct block *block,
+					  const domain_enum domain,
+					  struct symtab **symtab,
+					  int anonymous_namespace);
+
 /* Set up support for dealing with C++ namespace info in the current
    symtab.  */
 
@@ -262,5 +277,160 @@ cp_copy_usings (struct using_direct *usi
       xfree (using);
 
       return retval;
+    }
+}
+
+/* The C++-specific version of name lookup for static and global
+   names.  This makes sure that names get looked for in all namespaces
+   that are in scope.  */
+
+struct symbol *
+cp_lookup_symbol_nonlocal (const char *name,
+			   const char *linkage_name,
+			   const struct block *block,
+			   const domain_enum domain,
+			   struct symtab **symtab)
+{
+  return lookup_namespace_scope (name, linkage_name, block, domain,
+				 symtab, block_scope (block), 0);
+}
+
+/* Lookup NAME at namespace scope (or, in C terms, in static and
+   global variables).  SCOPE is the namespace that the current
+   function is defined within; only consider namespaces whose length
+   is at least SCOPE_LEN.  (This is to make the recursion easier.)  */
+
+static struct symbol *
+lookup_namespace_scope (const char *name,
+			const char *linkage_name,
+			const struct block *block,
+			const domain_enum domain,
+			struct symtab **symtab,
+			const char *scope,
+			int scope_len)
+{
+  char *namespace;
+
+  if (scope[scope_len] != '\0')
+    {
+      /* Recursively search for names in child namespaces first.  */
+
+      struct symbol *sym;
+      int new_scope_len = scope_len;
+
+      /* If the current scope is followed by "::", skip past that.  */
+      if (new_scope_len != 0)
+	{
+	  gdb_assert (scope[new_scope_len] == ':');
+	  new_scope_len += 2;
+	}
+      new_scope_len += cp_find_first_component (scope + new_scope_len);
+      sym = lookup_namespace_scope (name, linkage_name, block,
+				    domain, symtab,
+				    scope, new_scope_len);
+      if (sym != NULL)
+	return sym;
+    }
+
+  /* Okay, we didn't find a match in our parents, so look for the name
+     in the current namespace.  */
+
+  namespace = alloca (scope_len + 1);
+  strncpy (namespace, scope, scope_len);
+  namespace[scope_len] = '\0';
+  return cp_lookup_symbol_namespace (namespace, name, linkage_name,
+				     block, domain, symtab);
+}
+
+/* Look up NAME in the C++ namespace NAMESPACE, applying the using
+   directives that are active in BLOCK.  Otherwise, arguments are as
+   in lookup_symbol_aux.  */
+
+struct symbol *
+cp_lookup_symbol_namespace (const char *namespace,
+			    const char *name,
+			    const char *linkage_name,
+			    const struct block *block,
+			    const domain_enum domain,
+			    struct symtab **symtab)
+{
+  const struct using_direct *current;
+  struct symbol *sym;
+
+  /* First, go through the using directives.  If any of them add new
+     names to the namespace we're searching in, see if we can find a
+     match by applying them.  */
+
+  for (current = block_using (block);
+       current != NULL;
+       current = current->next)
+    {
+      if (strcmp (namespace, current->outer) == 0)
+	{
+	  sym = cp_lookup_symbol_namespace (current->inner,
+					    name,
+					    linkage_name,
+					    block,
+					    domain,
+					    symtab);
+	  if (sym != NULL)
+	    return sym;
+	}
+    }
+
+  /* We didn't find anything by applying any of the using directives
+     that are still applicable; so let's see if we've got a match
+     using the current namespace.  */
+  
+  if (namespace[0] == '\0')
+    {
+      return lookup_symbol_file (name, linkage_name, block,
+				 domain, symtab, 0);
+    }
+  else
+    {
+      char *concatenated_name
+	= alloca (strlen (namespace) + 2 + strlen (name) + 1);
+      strcpy (concatenated_name, namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, name);
+      sym = lookup_symbol_file (concatenated_name, linkage_name,
+				block, domain, symtab,
+				cp_is_anonymous (namespace));
+      return sym;
+    }
+}
+
+/* Look up NAME in BLOCK's static block and in global blocks.  If
+   ANONYMOUS_NAMESPACE is nonzero, don't look in other files' global
+   blocks, just in the one belonging to this file.  */
+
+static struct symbol *
+lookup_symbol_file (const char *name,
+		    const char *linkage_name,
+		    const struct block *block,
+		    const domain_enum domain,
+		    struct symtab **symtab,
+		    int anonymous_namespace)
+{
+  struct symbol *sym = NULL;
+
+  sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+  if (sym != NULL)
+    return sym;
+
+  if (anonymous_namespace)
+    {
+      const struct block *global_block = block_global_block (block);
+      
+      if (global_block != NULL)
+	return lookup_symbol_aux_block (name, linkage_name, global_block,
+					domain, symtab);
+      else
+	return NULL;
+    }
+  else
+    {
+      return lookup_symbol_global (name, linkage_name, domain, symtab);
     }
 }
Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.2
diff -u -p -r1.2 cp-support.h
--- cp-support.h	15 Apr 2003 23:07:11 -0000	1.2
+++ cp-support.h	18 May 2003 17:32:58 -0000
@@ -24,11 +24,14 @@
 #ifndef CP_SUPPORT_H
 #define CP_SUPPORT_H
 
+/* We need this for 'domain_enum', alas...  */
+
+#include "symtab.h"
+
 /* Opaque declarations.  */
 
 struct obstack;
 struct block;
-struct symbol;
 
 /* This struct is designed to store data from using directives.  It
    says that names from namespace INNER should be visible within
@@ -77,5 +80,18 @@ extern void cp_set_block_scope (const st
 				struct obstack *obstack);
 
 extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol);
+
+extern struct symbol *cp_lookup_symbol_nonlocal (const char *name,
+						 const char *linkage_name,
+						 const struct block *block,
+						 const domain_enum domain,
+						 struct symtab **symtab);
+
+extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
+						  const char *name,
+						  const char *linkage_name,
+						  const struct block *block,
+						  const domain_enum domain,
+						  struct symtab **symtab);
 
 #endif /* CP_SUPPORT_H */
--- block.c	2003-05-18 10:25:54.000000000 -0700
+++ block.c-2	2003-05-18 10:22:42.000000000 -0700
@@ -155,8 +155,25 @@ block_for_pc (register CORE_ADDR pc)
   return block_for_pc_sect (pc, find_pc_mapped_section (pc));
 }
 
-/* Now come some functions designed to deal with C++ namespace
-   issues.  */
+/* Now come some functions designed to deal with C++ namespace issues.
+   The accessors are safe to use even in the non-C++ case.  */
+
+/* This returns the namespace that BLOCK is enclosed in, or "" if it
+   isn't enclosed in a namespace at all.  This travels the chain of
+   superblocks looking for a scope, if necessary.  */
+
+const char *
+block_scope (const struct block *block)
+{
+  for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
+    {
+      if (BLOCK_NAMESPACE (block) != NULL
+	  && BLOCK_NAMESPACE (block)->scope != NULL)
+	return BLOCK_NAMESPACE (block)->scope;
+    }
+
+  return "";
+}
 
 /* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
    OBSTACK.  (It won't make a copy of SCOPE, however, so that already
@@ -171,6 +188,27 @@ block_set_scope (struct block *block, co
   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.  */
+
+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)
+    return NULL;
+  else
+    return BLOCK_NAMESPACE (static_block)->using;
+}
+
 /* Set BLOCK's using member to USING; if needed, allocate memory via
    OBSTACK.  (It won't make a copy of USING, however, so that already
    has to be allocated correctly.)  */
@@ -214,3 +252,18 @@ block_static_block (const struct block *
 
   return block;
 }
+
+/* Return the static block associated to BLOCK.  Return NULL if block
+   is NULL.  */
+
+const struct block *
+block_global_block (const struct block *block)
+{
+  if (block == NULL)
+    return NULL;
+
+  while (BLOCK_SUPERBLOCK (block) != NULL)
+    block = BLOCK_SUPERBLOCK (block);
+
+  return block;
+}
--- block.h	2003-05-18 10:25:54.000000000 -0700
+++ block.h-2	2003-05-18 10:22:37.000000000 -0700
@@ -200,13 +200,19 @@ extern struct block *block_for_pc (CORE_
 
 extern struct block *block_for_pc_sect (CORE_ADDR, asection *);
 
+extern const char *block_scope (const struct block *block);
+
 extern void block_set_scope (struct block *block, const char *scope,
 			     struct obstack *obstack);
 
+extern struct using_direct *block_using (const struct block *block);
+
 extern void block_set_using (struct block *block,
 			     struct using_direct *using,
 			     struct obstack *obstack);
 
 extern const struct block *block_static_block (const struct block *block);
 
+extern const struct block *block_global_block (const struct block *block);
+
 #endif /* BLOCK_H */
--- c-lang.c	2003-05-18 10:25:54.000000000 -0700
+++ c-lang.c-2	2003-05-18 10:22:47.000000000 -0700
@@ -32,6 +32,7 @@
 #include "charset.h"
 #include "gdb_string.h"
 #include "demangle.h"
+#include "cp-support.h"
 
 extern void _initialize_c_language (void);
 static void c_emit_char (int c, struct ui_file * stream, int quoter);
@@ -610,7 +611,7 @@ const struct language_defn cplus_languag
   c_value_print,		/* Print a top-level value */
   NULL,				/* Language specific skip_trampoline */
   1,				/* lookup_symbol_this */
-  basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
+  cp_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   cplus_demangle,		/* Language specific symbol demangler */
   {"", "", "", ""},		/* Binary format info */
   {"0%lo", "0", "o", ""},	/* Octal format info */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.377
diff -u -p -r1.377 Makefile.in
--- Makefile.in	15 May 2003 22:18:42 -0000	1.377
+++ Makefile.in	18 May 2003 17:32:43 -0000
@@ -626,7 +626,7 @@ complaints_h = complaints.h
 completer_h = completer.h
 config_h = config.h
 cp_abi_h = cp-abi.h
-cp_support_h = cp-support.h
+cp_support_h = cp-support.h $(symtab_h)
 dcache_h = dcache.h
 defs_h = defs.h $(config_h) $(gdb_locale_h) $(gdb_signals_h) $(ansidecl_h) \
 	$(libiberty_h) $(progress_h) $(bfd_h) $(tui_h) $(ui_file_h) $(xm_h) \
Index: namespace.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.exp,v
retrieving revision 1.12
diff -u -p -r1.12 namespace.exp
--- namespace.exp	10 Jan 2002 20:46:16 -0000	1.12
+++ namespace.exp	18 May 2003 17:18:06 -0000
@@ -1,4 +1,4 @@
-# Copyright 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright 1997, 1998, 2000, 2001, 2002, 2003 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
@@ -39,20 +39,26 @@ if { [skip_cplus_tests] } { continue }
 
 set testfile "namespace"
 set srcfile ${testfile}.cc
+set objfile ${objdir}/${subdir}/${testfile}.o
+set srcfile1 ${testfile}1.cc
+set objfile1 ${objdir}/${subdir}/${testfile}1.o
 set binfile ${objdir}/${subdir}/${testfile}
 
 if [get_compiler_info ${binfile}] {
     return -1;
 }
 
-
-
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
-     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will a
-utomatically fail."
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug c++}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
 }
 
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${objfile1}" object {debug c++}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
 
+if  { [gdb_compile "${objfile} ${objfile1}" "${binfile}" executable {debug c++}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
 
 gdb_exit
 gdb_start
@@ -186,3 +192,28 @@ gdb_expect {
    timeout { fail "(timeout) break BBB::Class::xyzq" }
 }
 
+# Test to see if the appropriate namespaces are in scope when trying
+# to print out stuff from within a function defined within a
+# namespace.
+
+if ![runto "C::D::marker2"] then {
+    perror "couldn't run to marker2"
+    continue
+}
+
+gdb_test "print c" "\\$\[0-9\].* = 1"
+gdb_test "print cc" "No symbol \"cc\" in current context."
+gdb_test "print 'C::cc'" "\\$\[0-9\].* = 2"
+gdb_test "print cd" "\\$\[0-9\].* = 3"
+gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
+gdb_test "print shadow" "\\$\[0-9\].* = 13"
+gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
+
+# Some anonymous namespace tests.
+
+gdb_test "print cX" "\\$\[0-9\].* = 6"
+gdb_test "print 'F::cXf'" "\\$\[0-9\].* = 7"
+gdb_test "print X" "\\$\[0-9\].* = 9"
+gdb_test "print 'G::Xg'" "\\$\[0-9\].* = 10"
+gdb_test "print cXOtherFile" "No symbol \"cXOtherFile\" in current context."
+gdb_test "print XOtherFile" "No symbol \"XOtherFile\" in current context."
Index: namespace.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.cc,v
retrieving revision 1.1
diff -u -p -r1.1 namespace.cc
--- namespace.cc	12 Jun 2000 01:31:41 -0000	1.1
+++ namespace.cc	18 May 2003 17:17:58 -0000
@@ -68,6 +68,70 @@ void marker1(void)
   return;
 }
 
+namespace
+{
+  int X = 9;
+
+  namespace G
+  {
+    int Xg = 10;
+  }
+}
+
+namespace C
+{
+  int c = 1;
+  int shadow = 12;
+
+  namespace
+  {
+    int cX = 6;
+    
+    namespace F
+    {
+      int cXf = 7;
+    }
+  }
+
+  namespace C
+  {
+    int cc = 2;
+  }
+
+  namespace D
+  {
+    int cd = 3;
+    int shadow = 13;
+
+    namespace E
+    {
+      int cde = 5;
+    }
+
+    void marker2 (void)
+    {
+      // NOTE: carlton/2003-04-23: I'm listing the expressions that I
+      // plan to have GDB try to print out, just to make sure that the
+      // compiler and I agree which ones should be legal!  It's easy
+      // to screw up when testing the boundaries of namespace stuff.
+      c;
+      //cc;
+      C::cc;
+      cd;
+      E::cde;
+      shadow;
+      cX;
+      F::cXf;
+      X;
+      G::Xg;
+      //cXOtherFile;
+      //XOtherFile;
+
+      return;
+    }
+
+  }
+}
 
 int main ()
 {
@@ -95,9 +159,5 @@ int main ()
 
   marker1();
   
+  C::D::marker2 ();
 }
-
-  
-
-
-
--- /dev/null	2002-08-30 16:31:37.000000000 -0700
+++ namespace1.cc	2003-05-18 10:16:49.000000000 -0700
@@ -0,0 +1,31 @@
+/* Copyright 2003 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+namespace C
+{
+  namespace {
+    int cXOtherFile = 29;
+  };
+
+  int cOtherFile = 316;
+}
+
+namespace {
+  int XOtherFile = 317;
+}
Index: fnchange.lst
===================================================================
RCS file: /cvs/src/src/gdb/config/djgpp/fnchange.lst,v
retrieving revision 1.48
diff -u -p -r1.48 fnchange.lst
--- fnchange.lst	12 May 2003 00:26:18 -0000	1.48
+++ fnchange.lst	18 May 2003 17:19:34 -0000
@@ -244,6 +244,7 @@
 @V@/gdb/testsuite/gdb.c++/misc.cc @V@/gdb/testsuite/gdb.cxx/misc.cc
 @V@/gdb/testsuite/gdb.c++/misc.exp @V@/gdb/testsuite/gdb.cxx/misc.exp
 @V@/gdb/testsuite/gdb.c++/namespace.cc @V@/gdb/testsuite/gdb.cxx/namespace.cc
+@V@/gdb/testsuite/gdb.c++/namespace1.cc @V@/gdb/testsuite/gdb.cxx/namesp1.cc
 @V@/gdb/testsuite/gdb.c++/namespace.exp @V@/gdb/testsuite/gdb.cxx/namespace.exp
 @V@/gdb/testsuite/gdb.c++/overload.cc @V@/gdb/testsuite/gdb.cxx/overload.cc
 @V@/gdb/testsuite/gdb.c++/overload.exp @V@/gdb/testsuite/gdb.cxx/overload.exp


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