Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [drow-cplus-branch] handle namespace scope
@ 2002-11-19 15:07 David Carlton
  2002-11-21  9:40 ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: David Carlton @ 2002-11-19 15:07 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

Here are some patches for drow-cplus-branch that teach lookup_symbol
and buildsym.c about the concept of "namespace scope".  Basically, if
you have a function like this

namespace A
{
  void foo ()
  {
    // body of foo
  }
}

then, when doing name lookup within A::foo, when you hit the part
where you'd normally search the global environment, you first search
namespace A and then search the global namespace.  My previous patches
had faked this by behaving as if there were a using directive "using
namespace A;" at the start of the body of foo; this patch does it
right.

One side effect of this is that struct block now has to have room for
the current namespace as well as the current using directives; I
decided to implement this in such a way as to use a little more memory
in the C++ case but a little less memory in the non-C++ case.  (This
also lead to a bunch of block accessor functions; I put them in
symtab.{c,h}, but the block stuff should really be in block.{c,h}.
I've done that on my branch, but I won't worry about that in
drow-cplus-branch until it's that way on the mainline.)

There's also a little bit of futzing around with lookup_symbol_aux, to
treat minsyms in a better way than I treated them in my last patch.  I
didn't include the patch from
<http://sources.redhat.com/ml/gdb-patches/2002-11/msg00378.html> that
moves the field_of_this check to the right place, since that's
somewhat orthogonal to this issue, but if you want I can include that
as well.

This should get everything important out of the way before I start
trying to add symbols associated to namespaces...

Okay to commit?

David Carlton
carlton@math.stanford.edu

2002-11-19  David Carlton  <carlton@math.stanford.edu>

	* symtab.h: Add opaque declarations for struct namespace_info and
	struct obstack.
	(struct block): The language_specific stuff is now a struct
	namespace_info rather than a struct using_direct_node.
	(BLOCK_NAMESPACE): New macro.
	Delete macro BLOCK_USING.
	Add declarations for block_using, block_all_usings,
	block_set_using, block_scope, block_set_scope.
	* symtab.c: #include "gdb_assert.h"
	(lookup_symbol_aux): Move minsym stuff inside
	lookup_symbol_aux_nonlocal, and always do global search via
	lookup_symbol_aux_using.
	(lookup_symbol_aux_nonlocal): Do minsym search.
	(lookup_symbol_aux_using): Calculate usings via block_all_usings;
	handle namespace scope.
	(lookup_symbol_aux_using_loop): New function, not to be confused
	with the previous function of the same name.  (Sorry about that.)
	(lookup_symbol_namespace): Renamed from
	lookup_symbol_aux_using_loop.
	(lookup_symbol_aux_minsyms): Add block_index argument, delete
	is_a_field_of_this argument, and only check either global or
	static symbols rather than both of them.
	(block_using): New function.
	(block_all_usings): New function.
	(block_set_using): New function.
	(block_scope): New function.
	(block_set_scope): New function.
	(block_initialize_namespace): New function.
	* jv-lang.c (get_java_class_symtab): BLOCK_NAMESPACE instead of
	BLOCK_USING.
	* dwarf2read.c: Delete variable current_namespace, and replace its
	uses by processing_current_namespace (from buildsym.h).
	* cp-support.h (struct namespace_info): New struct.
	* cp-support.c: Add comment.
	* buildsym.h: New variable processing_current_namespace.
	* buildsym.c (add_symbol_to_list): Do fast search for
	"(anonymous namespace)".
	(scan_for_anonymous_namespaces): Delete FIXME.
	(finish_block): Replace BLOCK_USING by BLOCK_NAMESPACE.
	(finish_block): Set block_scope of function blocks rather than
	generating using directives that would have a similar effect.
	(end_symtab): Set using via block_set_using rather than
	BLOCK_USING.
	* Makefile.in (symtab.o): Depend on gdb_assert_h.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.268.2.2
diff -u -p -r1.268.2.2 Makefile.in
--- Makefile.in	26 Oct 2002 17:12:03 -0000	1.268.2.2
+++ Makefile.in	19 Nov 2002 22:35:53 -0000
@@ -2206,7 +2206,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h)
 	$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
 	$(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
-	$(cp_abi_h) $(source_h) $(cp_support_h)
+	$(cp_abi_h) $(source_h) $(cp_support_h) $(gdb_assert_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h)
Index: buildsym.c
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.c,v
retrieving revision 1.20.4.1
diff -u -p -r1.20.4.1 buildsym.c
--- buildsym.c	22 Oct 2002 19:59:36 -0000	1.20.4.1
+++ buildsym.c	19 Nov 2002 22:35:53 -0000
@@ -160,7 +160,9 @@ add_symbol_to_list (struct symbol *symbo
   
    if (SYMBOL_LANGUAGE (symbol) == language_cplus
        && !processing_has_namespace_info
-       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
+       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL
+       && strstr (SYMBOL_CPLUS_DEMANGLED_NAME (symbol),
+		  "(anonymous namespace)") != NULL)
      scan_for_anonymous_namespaces (symbol);
 }
 
@@ -177,10 +179,6 @@ scan_for_anonymous_namespaces (struct sy
   const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
   const char *beginning, *end;
 
-  /* FIXME: carlton/2002-10-14: Should we do some sort of fast search
-     first to see if the substring "(anonymous namespace)" occurs in
-     name at all?  */
-
   for (beginning = name, end = cp_find_first_component (name);
        *end == ':';
        /* The "+ 2" is for the "::"-.  */
@@ -384,7 +382,7 @@ finish_block (struct symbol *symbol, str
   BLOCK_END (block) = end;
   /* Superblock filled in when containing block is made */
   BLOCK_SUPERBLOCK (block) = NULL;
-  BLOCK_USING (block) = NULL;
+  BLOCK_NAMESPACE (block) = NULL;
 
   BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
 
@@ -485,21 +483,36 @@ finish_block (struct symbol *symbol, str
 	  const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
 	  const char *next;
 
-	  for (next = cp_find_first_component (name);
-	       *next == ':';
-	       /* The '+ 2' is to skip the '::'.  */
-	       next = cp_find_first_component (next + 2))
+if (processing_has_namespace_info)
+	    block_set_scope (block, processing_current_namespace,
+			     &objfile->symbol_obstack);
+	  else
 	    {
-	      BLOCK_USING (block)
-		= cp_add_using_obstack (name, 0, next - name,
-					BLOCK_USING (block),
-					&objfile->symbol_obstack);
-	    }
+	      const char *current, *next;
 
-	  /* FIMXE: carlton/2002-10-09: Until I understand the
-	     possible pitfalls of demangled names a lot better, I want
-	     to make sure I'm not running into surprises.  */
-	  gdb_assert (*next == '\0');
+	      /* FIXME: carlton/2002-11-14: For members of classes,
+		 with this include the class name as well?  I don't
+		 think that's a problem yet, but it will be.  */
+	      
+	      for (current = name, next = cp_find_first_component (current);
+		   *next == ':';
+		   /* The '+ 2' is to skip the '::'.  */
+		   current = next,
+		     next = cp_find_first_component (current + 2))
+		;
+	      if (current == name)
+		block_set_scope (block, "", &objfile->symbol_obstack);
+	      else
+		block_set_scope (block,
+				 obsavestring (name, current - name,
+					       &objfile->symbol_obstack),
+				 &objfile->symbol_obstack);
+	      
+	      /* FIXME: carlton/2002-10-09: Until I understand the
+		 possible pitfalls of demangled names a lot better, I
+		 want to make sure I'm not running into surprises.  */
+	      gdb_assert (*next == '\0');
+	    }
 	}
     }
   else
@@ -1063,9 +1076,10 @@ end_symtab (CORE_ADDR end_addr, struct o
       blockvector = make_blockvector (objfile);
       if (using_list != NULL)
 	{
-	  BLOCK_USING (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK))
-	    = copy_usings_to_obstack (using_list,
-				      &objfile->symbol_obstack);
+	  block_set_using (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
+			   copy_usings_to_obstack (using_list,
+						   &objfile->symbol_obstack),
+			   &objfile->symbol_obstack);
 	  using_list = NULL;
 	}
     }
Index: buildsym.h
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.h,v
retrieving revision 1.5.10.1
diff -u -p -r1.5.10.1 buildsym.h
--- buildsym.h	22 Oct 2002 19:59:36 -0000	1.5.10.1
+++ buildsym.h	19 Nov 2002 22:35:53 -0000
@@ -99,6 +99,13 @@ EXTERN unsigned char processing_hp_compi
 
 EXTERN unsigned char processing_has_namespace_info;
 
+/* If processing_has_namespace_info is nonzero, this string should
+   contain the name of the current namespace.  Other people shouldn't
+   have to copy it when referring to it, so don't free its previous
+   contents when setting this to a new value.  */
+
+EXTERN const char *processing_current_namespace;
+
 /* Count symbols as they are processed, for error messages.  */
 
 EXTERN unsigned int symnum;
Index: cp-support.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.c,v
retrieving revision 1.1.6.1
diff -u -p -r1.1.6.1 cp-support.c
--- cp-support.c	22 Oct 2002 19:59:36 -0000	1.1.6.1
+++ cp-support.c	19 Nov 2002 22:35:53 -0000
@@ -52,6 +52,12 @@
      fairly restrictive set of locations (in particular, they have be
      at depth 0, don't they?).  */
 
+/* NOTE: carlton/2002-10-25: Daniel Jacobowitz came up with an example
+   where operator names don't occur at depth 0.  Sigh.  (It involved a
+   template argument that was a pointer: I hadn't realized that was
+   possible.)  Handling such edge cases does not seem like a
+   high-priority problem to me.  */
+
 /* FIXME: carlton/2002-10-09: Do all the functions here handle all the
    above considerations correctly?  */
 
Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.1.6.1
diff -u -p -r1.1.6.1 cp-support.h
--- cp-support.h	22 Oct 2002 19:59:36 -0000	1.1.6.1
+++ cp-support.h	19 Nov 2002 22:35:53 -0000
@@ -67,6 +67,16 @@ struct using_direct_node
   struct using_direct_node *next;
 };
 
+/* This is used by struct block to store namespace-related info for
+   C++ files, namely using declarations and the current namespace in
+   scope.  */
+
+struct namespace_info
+{
+  struct using_direct_node *using;
+  const char *scope;
+};
+
 extern struct
 using_direct_node *cp_add_using_obstack (const char *name,
 					 unsigned short outer_length,
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.67.2.2
diff -u -p -r1.67.2.2 dwarf2read.c
--- dwarf2read.c	26 Oct 2002 17:12:06 -0000	1.67.2.2
+++ dwarf2read.c	19 Nov 2002 22:35:54 -0000
@@ -388,13 +388,6 @@ static struct partial_die_info zeroed_pa
    in buildsym.c.  */
 static struct pending **list_in_scope = &file_symbols;
 
-/* If we're debugging C++ code, this string should contain the name of
-   the current namespace.  Other people shouldn't have to copy it when
-   referring to it, so don't free its previous contents when setting
-   this to a new value.  */
-
-static const char *current_namespace;
-
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
@@ -1632,7 +1625,7 @@ psymtab_to_symtab_1 (struct partial_symt
   info_ptr = dwarf_info_buffer + offset;
 
   /* We're in the global namespace.  */
-  current_namespace = "";
+  processing_current_namespace = "";
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -2998,7 +2991,7 @@ static void
 read_namespace (struct die_info *die, struct objfile *objfile,
 		const struct comp_unit_head *cu_header)
 {
-  const char *previous_namespace = current_namespace;
+  const char *previous_namespace = processing_current_namespace;
   const char *name = NULL;
   int is_anonymous;
   struct die_info *current_die;
@@ -3021,18 +3014,19 @@ read_namespace (struct die_info *die, st
 
   /* Now build the name of the current namespace.  */
 
-  current_namespace = obconcat (&objfile->symbol_obstack,
-				previous_namespace,
-				previous_namespace[0] == '\0' ? "" : "::",
-				name);
+  processing_current_namespace = obconcat (&objfile->symbol_obstack,
+					   previous_namespace,
+					   previous_namespace[0] == '\0'
+					   ? "" : "::",
+					   name);
 
   /* If it's an anonymous namespace that we're seeing for the first
      time, add a using directive.  */
 
   if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
-    add_using_directive (current_namespace,
+    add_using_directive (processing_current_namespace,
 			 strlen (previous_namespace),
-			 strlen (current_namespace));
+			 strlen (processing_current_namespace));
   
   
   if (die->has_children)
@@ -3046,7 +3040,7 @@ read_namespace (struct die_info *die, st
 	}
     }
 
-  current_namespace = previous_namespace;
+  processing_current_namespace = previous_namespace;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
Index: jv-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-lang.c,v
retrieving revision 1.12.10.1
diff -u -p -r1.12.10.1 jv-lang.c
--- jv-lang.c	22 Oct 2002 19:59:36 -0000	1.12.10.1
+++ jv-lang.c	19 Nov 2002 22:35:54 -0000
@@ -111,7 +111,7 @@ get_java_class_symtab (void)
       BLOCK_END (bl) = 0;
       BLOCK_FUNCTION (bl) = NULL;
       BLOCK_SUPERBLOCK (bl) = NULL;
-      BLOCK_USING (bl) = NULL;
+      BLOCK_NAMESPACE (bl) = NULL;
       BLOCK_GCC_COMPILED (bl) = 0;
       BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
 
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.70.4.3
diff -u -p -r1.70.4.3 symtab.c
--- symtab.c	26 Oct 2002 17:12:09 -0000	1.70.4.3
+++ symtab.c	19 Nov 2002 22:35:54 -0000
@@ -50,6 +50,7 @@
 #include <ctype.h>
 #include "cp-abi.h"
 #include "cp-support.h"
+#include "gdb_assert.h"
 
 /* Prototypes for local functions */
 
@@ -119,22 +120,30 @@ struct symbol *lookup_symbol_aux_using (
 					struct symtab **symtab);
 
 static
-struct symbol *lookup_symbol_aux_using_loop (const char *prefix,
-					     int prefix_len,
-					     const char *rest,
-					     struct using_direct_node *using,
+struct symbol *lookup_symbol_aux_using_loop (const char *name,
 					     const char *mangled_name,
 					     namespace_enum namespace,
-					     struct symtab **symtab);
+					     struct symtab **symtab,
+					     const char *scope,
+					     int scope_len,
+					     struct using_direct_node *using);
 
 static
-struct symbol *lookup_symbol_aux_minsyms (const char *name,
+struct symbol *lookup_symbol_namespace (const char *prefix,
+					int prefix_len,
+					const char *rest,
+					struct using_direct_node *using,
+					const char *mangled_name,
+					namespace_enum namespace,
+					struct symtab **symtab);
+
+static
+struct symbol *lookup_symbol_aux_minsyms (int block_index,
+					  const char *name,
 					  const char *mangled_name,
 					  const namespace_enum namespace,
-					  int *is_a_field_of_this,
 					  struct symtab **symtab);
 
-
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
 
 /* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
@@ -154,6 +163,9 @@ static void symtab_symbol_info (char *, 
 
 static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
 
+static void block_initialize_namespace (struct block *block,
+					struct obstack *obstack);
+
 void _initialize_symtab (void);
 
 /* */
@@ -842,84 +854,35 @@ lookup_symbol_aux (const char *name, con
 	}
     }
 
-  /* Now search all global blocks.  Do the symtab's first, then
-     check the psymtab's. If a psymtab indicates the existence
-     of the desired name as a global, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
-
-  sym = lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, name, mangled_name,
-				    namespace, symtab);
-  if (sym != NULL)
-    return sym;
-
-  /* If we're in the C++ case, check to see if the symbol is defined
-     in a namespace accessible via a "using" declaration.  */
-
-  /* FIXME: carlton/2002-10-10: is "is_a_field_of_this" always
-     non-NULL if we're in the C++ case?  Maybe we should always do
-     this, and delete the two previous searches: this will always
-     search the global namespace, after all.  */
-
-  if (is_a_field_of_this)
-    {
-      sym = lookup_symbol_aux_using (name, mangled_name, block, namespace,
-				     symtab);
-      if (sym != NULL)
-	return sym;
-    }
-
-#ifndef HPUXHPPA
+  /* Now search all global blocks.  Do the symtab's first, then the
+     minsyms, then check the psymtab's. If minsyms or psymtabs
+     indicate the existence of the desired name as a global, then
+     generate the appropriate symtab on the fly and return the found
+     symbol.
+
+     We do this from within lookup_symbol_aux_using: that will apply
+     appropriate using directives in the C++ case.  But it works fine
+     in the non-C++ case, too.  */
+
+  /* NOTE: carlton/2002-10-22: Is it worthwhile to try to figure out
+     whether or not we're in the C++ case?  Doing
+     lookup_symbol_aux_using won't slow things down significantly in
+     the general case, though: other parts of this function are much,
+     much more expensive.  */
 
-  /* Check for the possibility of the symbol being a function or a
-     mangled variable that is stored in one of the minimal symbol
-     tables.  Eventually, all global symbols might be resolved in this
-     way.  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-				   namespace, is_a_field_of_this,
-				   symtab);
+  sym = lookup_symbol_aux_using (name, mangled_name, block, namespace,
+				 symtab);
   if (sym != NULL)
     return sym;
 
-#endif
-
   /* Now search all static file-level symbols.  Not strictly correct,
-     but more useful than an error.  Do the symtabs first, then check
-     the psymtabs.  If a psymtab indicates the existence of the
-     desired name as a file-level static, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
+     but more useful than an error.  */
 
   sym = lookup_symbol_aux_nonlocal (STATIC_BLOCK, name, mangled_name,
 				    namespace, symtab);
   if (sym != NULL)
     return sym;
 
-#ifdef HPUXHPPA
-
-  /* Check for the possibility of the symbol being a function or a
-     global variable that is stored in one of the minimal symbol
-     tables.  The "minimal symbol table" is built from linker-supplied
-     info.
-
-     RT: I moved this check to last, after the complete search of the
-     global (p)symtab's and static (p)symtab's. For HP-generated
-     symbol tables, this check was causing a premature exit from
-     lookup_symbol with NULL return, and thus messing up symbol
-     lookups of things like "c::f". It seems to me a check of the
-     minimal symbol table ought to be a last resort in any case. I'm
-     vaguely worried about the comment within
-     lookup_symbol_aux_minsyms which talks about FORTRAN routines
-     "foo_" though... is it saying we need to do the "minsym" check
-     before the static check in this case?  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-				   namespace, is_a_field_of_this,
-				   symtab);
-  if (sym != NULL)
-    return sym;
-
-#endif
-
   if (symtab != NULL)
     *symtab = NULL;
   return NULL;
@@ -975,9 +938,6 @@ lookup_symbol_aux_local (const char *nam
    STATIC_BLOCK, depending on whether or not we want to search global
    symbols or static symbols.  */
 
-/* FIXME: carlton/2002-10-11: Should this also do some minsym
-   lookup?  */
-
 static struct symbol *
 lookup_symbol_aux_nonlocal (int block_index,
 			    const char *name,
@@ -992,8 +952,63 @@ lookup_symbol_aux_nonlocal (int block_in
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (block_index, name, mangled_name,
-				     namespace, symtab);
+#ifndef HPUXHPPA
+  sym = lookup_symbol_aux_minsyms (block_index, name, mangled_name,
+				   namespace, symtab);
+  if (sym != NULL)
+    return sym;
+#endif
+
+  sym = lookup_symbol_aux_psymtabs (block_index, name, mangled_name,
+				    namespace, symtab);
+  if (sym != NULL)
+    return sym;
+
+#ifdef HPUXHPPA
+
+  /* FIXME: carlton/2002-10-28: The following comment was present in
+     lookup_symbol_aux before I broke it up: at that time, the HP
+     search order for nonlocal stuff was global symtab, global
+     psymtab, static symtab, static psymtab, global and static
+     minsyms.  (The minsyms are stored so that it's just as easy to do
+     global and static searches of them at the same time.)  Now it's
+     global symtab, global psymtab, global minsyms, static symtab,
+     static psymtab, static minsyms.  Also, it's now impossible for a
+     global minsym search to cause a NULL return by itself: if a
+     minsym search returns NULL, then the next search after that is
+     still performed.
+
+     Given that that's the case, I'm pretty sure that my search order
+     is safe; indeed, given that the comment below warns against
+     premature NULL returns, it even seems plausible to me that we can
+     treat HP symbol tables the same as non-HP symbol tables.  It
+     would be great if somebody who has access to HP machines (or,
+     even better, who understands the reason behind the HP special
+     case in the first place) could check on this.
+
+     But there's still the comment about "foo_" symbols in
+     lookup_symbol_aux_minsyms which I really don't understand, sigh.
+     _Should_ a minsym lookup sometimes be able to force a NULL return
+     from lookup_symbol?  */
+
+  /* RT: I moved this check to last, after the complete search of the
+     global (p)symtab's and static (p)symtab's. For HP-generated
+     symbol tables, this check was causing a premature exit from
+     lookup_symbol with NULL return, and thus messing up symbol
+     lookups of things like "c::f". It seems to me a check of the
+     minimal symbol table ought to be a last resort in any case. I'm
+     vaguely worried about the comment within
+     lookup_symbol_aux_minsyms which talks about FORTRAN routines
+     "foo_" though... is it saying we need to do the "minsym" check
+     before the static check in this case?  */
+
+  sym = lookup_symbol_aux_minsyms (block_index, name, mangled_name,
+				   namespace, symtab);
+  if (sym != NULL)
+    return sym;
+#endif
+
+  return NULL;
 }
 
 /* Check to see if the symbol is defined in one of the symtabs.
@@ -1092,32 +1107,69 @@ lookup_symbol_aux_psymtabs (int block_in
 /* This function gathers using directives from BLOCK and its
    superblocks, and then searches for symbols in the global namespace
    by trying to apply those various using directives.  */
+
 static struct symbol *lookup_symbol_aux_using (const char *name,
 					       const char *mangled_name,
 					       const struct block *block,
 					       const namespace_enum namespace,
 					       struct symtab **symtab)
 {
-  struct using_direct_node *using = NULL;
+  struct using_direct_node *using;
+  const char *scope;
   struct symbol *sym;
 
-  while (block != NULL)
-    {
-      using = cp_copy_usings (BLOCK_USING (block), using);
-      block = BLOCK_SUPERBLOCK (block);
-    }
-
-  sym = lookup_symbol_aux_using_loop ("", 0, name, using, mangled_name,
-				      namespace, symtab);
+  using = block_all_usings (block);
+  scope = block_scope (block);
+  
+  sym = lookup_symbol_aux_using_loop (name, mangled_name, namespace, symtab,
+				      scope, 0, using);
   cp_free_usings (using);
   
   return sym;
 }
 
+/* Look up NAME in the namespaces given by SCOPE and its initial
+   prefixes, applying using directives given by USING; only consider
+   prefixes that are at least as long as SCOPE_LEN, however.  Look up
+   longest prefixes first.  */
+
+static struct
+symbol *lookup_symbol_aux_using_loop (const char *name,
+				      const char *mangled_name,
+				      namespace_enum namespace,
+				      struct symtab **symtab,
+				      const char *scope,
+				      int scope_len,
+				      struct using_direct_node *using)
+{
+  if (scope[scope_len] != '\0')
+    {
+      struct symbol *sym;
+      int next_component;
+      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;
+	}
+      next_component = cp_find_first_component (scope + new_scope_len) - scope;
+      sym = lookup_symbol_aux_using_loop (name, mangled_name, namespace,
+					  symtab, scope, next_component,
+					  using);
+      if (sym != NULL)
+	return sym;
+    }
+
+  return lookup_symbol_namespace (scope, scope_len, name, using,
+				  mangled_name, namespace, symtab);
+}
+
 /* This tries to look up REST in the namespace given by the initial
    substring of PREFIX of length PREFIX_LEN.
 
-   Basically, assume that we have using directives adding A to the
+   For example, assume that we have using directives adding A to the
    global namespace, adding A::inner to namespace A, and adding B to
    the global namespace.  Then, when looking up a symbol "foo", we
    want to recurse by looking up stuff in A::foo and seeing which
@@ -1138,14 +1190,19 @@ static struct symbol *lookup_symbol_aux_
    namespaces first-class objects.  (Which is certainly a good idea
    for other reasons, but it will take a little while.)  */
 
+/* NOTE: carlton/2002-11-19: This is optimistically called
+   lookup_symbol_namespace instead of lookup_symbol_aux_namespace in
+   hopes that it or something like it might eventually be useful
+   outside of lookup_symbol.  */
+
 static struct symbol *
-lookup_symbol_aux_using_loop (const char *prefix,
-			      int prefix_len,
-			      const char *rest,
-			      struct using_direct_node *using,
-			      const char *mangled_name,
-			      namespace_enum namespace,
-			      struct symtab **symtab)
+lookup_symbol_namespace (const char *prefix,
+			 int prefix_len,
+			 const char *rest,
+			 struct using_direct_node *using,
+			 const char *mangled_name,
+			 namespace_enum namespace,
+			 struct symtab **symtab)
 {
   struct using_direct_node *current;
   struct symbol *sym;
@@ -1179,14 +1236,13 @@ lookup_symbol_aux_using_loop (const char
 	      if (*new_rest == ':')
 		new_rest += 2;
 
-	      sym = lookup_symbol_aux_using_loop
-		(current->current->name,
-		 current->current->inner_length,
-		 new_rest,
-		 using,
-		 mangled_name,
-		 namespace,
-		 symtab);
+	      sym = lookup_symbol_namespace (current->current->name,
+					     current->current->inner_length,
+					     new_rest,
+					     using,
+					     mangled_name,
+					     namespace,
+					     symtab);
 	      if (sym != NULL)
 		return sym;
 	    }
@@ -1223,10 +1279,9 @@ lookup_symbol_aux_using_loop (const char
    way.  */
 
 static struct symbol *
-lookup_symbol_aux_minsyms (const char *name,
+lookup_symbol_aux_minsyms (int block_index, const char *name,
 			   const char *mangled_name,
 			   const namespace_enum namespace,
-			   int *is_a_field_of_this,
 			   struct symtab **symtab)
 {
   struct symbol *sym;
@@ -1250,7 +1305,30 @@ lookup_symbol_aux_minsyms (const char *n
 	     know about demangled names, but we were given a mangled
 	     name...  */
 
-	  /* We first use the address in the msymbol to try to locate
+	  /* First, check to see that the symbol looks like it's
+	     global or static (depending on what we were asked to look
+	     for).  */
+
+	  /* NOTE: carlton/2002-10-28: lookup_minimal_symbol gives
+	     preference to global symbols over static symbols, so if
+	     block_index is STATIC_BLOCK then this might well miss
+	     static symbols that are shadowed by global symbols.  But
+	     that's okay: this is only called with block_index equal
+	     to STATIC_BLOCK if a global search has failed.  */
+
+	  switch (MSYMBOL_TYPE (msymbol))
+	    {
+	    case mst_file_text:
+	    case mst_file_data:
+	    case mst_file_bss:
+	      if (block_index == GLOBAL_BLOCK)
+		return NULL;
+	    default:
+	      if (block_index == STATIC_BLOCK)
+		return NULL;
+	    }
+	  
+	  /* We next use the address in the msymbol to try to locate
 	     the appropriate symtab. Note that find_pc_sect_symtab()
 	     has a side-effect of doing psymtab-to-symtab expansion,
 	     for the found symtab.  */
@@ -1260,7 +1338,7 @@ lookup_symbol_aux_minsyms (const char *n
 	    {
 	      /* This is a function which has a symtab for its address.  */
 	      bv = BLOCKVECTOR (s);
-	      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	      block = BLOCKVECTOR_BLOCK (bv, block_index);
 
 	      /* This call used to pass `SYMBOL_NAME (msymbol)' as the
 	         `name' argument to lookup_block_symbol.  But the name
@@ -1269,14 +1347,16 @@ lookup_symbol_aux_minsyms (const char *n
 	         unmangled name.  */
 	      sym =
 		lookup_block_symbol (block, name, mangled_name, namespace);
-	      /* We kept static functions in minimal symbol table as well as
-	         in static scope. We want to find them in the symbol table. */
-	      if (!sym)
-		{
-		  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-		  sym = lookup_block_symbol (block, name,
-					     mangled_name, namespace);
-		}
+
+	      /* FIXME: carlton/2002-10-28: this next comment dates
+		 from when this code was part of lookup_symbol_aux, so
+		 this return could return NULL from lookup_symbol_aux.
+		 Are there really situations where we want a minimal
+		 symbol lookup to be able to force a NULL return from
+		 lookup_symbol?  If so, maybe the thing to do would be
+		 to have lookup_symbol_aux_minsym to set a
+		 minsym_found flag, and to have lookup_symbol_aux only
+		 do the psymtab search if that flag is zero.  */
 
 	      /* sym == 0 if symbol was found in the minimal symbol table
 	         but not in the symtab.
@@ -1297,13 +1377,15 @@ lookup_symbol_aux_minsyms (const char *n
 	    }
 	  else if (MSYMBOL_TYPE (msymbol) != mst_text
 		   && MSYMBOL_TYPE (msymbol) != mst_file_text
-		   && !STREQ (name, SYMBOL_NAME (msymbol)))
+		   && strcmp (name, SYMBOL_NAME (msymbol)) != 0)
 	    {
 	      /* This is a mangled variable, look it up by its
 	         mangled name.  */
-	      return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
-					NULL, namespace, is_a_field_of_this,
-					symtab);
+	      return lookup_symbol_aux_nonlocal (block_index,
+						 SYMBOL_NAME (msymbol),
+						 mangled_name,
+						 namespace,
+						 symtab);
 	    }
 	}
     }
@@ -3275,6 +3357,96 @@ contained_in (struct block *a, struct bl
   return BLOCK_START (a) >= BLOCK_START (b)
     && BLOCK_END (a) <= BLOCK_END (b);
 }
+
+/* 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 using directives associated to BLOCK (but _not_
+   its parents), if any.  */
+
+struct using_direct_node *
+block_using (const struct block *block)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    return NULL;
+  else
+    return BLOCK_NAMESPACE (block)->using;
+}
+
+/* This returns the using directives associated to BLOCK and its
+   parents, if any.  The resulting structure must be freed by calling
+   cp_free_usings on it.  */
+
+struct using_direct_node *
+block_all_usings (const struct block *block)
+{
+  struct using_direct_node *using = NULL;
+
+  while (block != NULL)
+    {
+      using = cp_copy_usings (block_using (block), using);
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  return using;
+}
+
+/* Set block_using (BLOCK) to USING; if needed, allocate memory via
+   OBSTACK.  */
+
+void
+block_set_using (struct block *block, struct using_direct_node *using,
+		 struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->using = using;
+}
+
+/* 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_scope (BLOCK) to SCOPE; if needed, allocate memory via
+   OBSTACK.  (It won't make a copy of SCOPE, however, so that already
+   has to be allocated correctly.)  */
+
+void
+block_set_scope (struct block *block, const char *scope,
+		 struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->scope = scope;
+}
+
+/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
+   ititialize its members to zero.  */
+
+static void
+block_initialize_namespace (struct block *block, struct obstack *obstack)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    {
+      BLOCK_NAMESPACE (block)
+	= obstack_alloc (obstack, sizeof (struct namespace_info));
+      BLOCK_NAMESPACE (block)->using = NULL;
+    }
+}
+
 \f
 
 /* Helper routine for make_symbol_completion_list.  */
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.42.4.2
diff -u -p -r1.42.4.2 symtab.h
--- symtab.h	26 Oct 2002 17:12:09 -0000	1.42.4.2
+++ symtab.h	19 Nov 2002 22:35:54 -0000
@@ -25,7 +25,9 @@
 
 /* Opaque declarations.  */
 struct obstack;
+struct namespace_info;
 struct using_direct_node;
+struct obstack;
 
 /* Don't do this; it means that if some .o's are compiled with GNU C
    and some are not (easy to do accidentally the way we configure
@@ -374,12 +376,11 @@ struct block
   {
     struct
     {
-      /* Contains information about what using directives or other
-	 similar features are added by this block.  This should always
-	 be NULL for global blocks: if there are using directives that
-	 affect an entire file, put it in the static block.  */
+      /* Contains information about namespace-related info relevant to
+	 this block: using directives and the current namespace
+	 scope.  */
       
-      struct using_direct_node *using;
+      struct namespace_info *namespace;
     }
     cplus_specific;
   }
@@ -430,7 +431,7 @@ struct block
 #define BLOCK_END(bl)		(bl)->endaddr
 #define BLOCK_FUNCTION(bl)	(bl)->function
 #define BLOCK_SUPERBLOCK(bl)	(bl)->superblock
-#define BLOCK_USING(bl)		(bl)->language_specific.cplus_specific.using
+#define BLOCK_NAMESPACE(bl)	(bl)->language_specific.cplus_specific.namespace
 #define BLOCK_GCC_COMPILED(bl)	(bl)->gcc_compile_flag
 #define BLOCK_HASHTABLE(bl)	(bl)->hashtable
 
@@ -1143,6 +1144,19 @@ extern struct partial_symbol *find_pc_se
 extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
 
 extern int contained_in (struct block *, struct block *);
+
+extern struct using_direct_node *block_using (const struct block *);
+
+extern struct using_direct_node *block_all_usings (const struct block *block);
+
+extern void block_set_using (struct block *block,
+			     struct using_direct_node *using,
+			     struct obstack *obstack);
+
+extern const char *block_scope (const struct block *block);
+
+extern void block_set_scope (struct block *block, const char *scope,
+			     struct obstack *obstack);
 
 extern void reread_symbols (void);
 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [drow-cplus-branch] handle namespace scope
  2002-11-19 15:07 [drow-cplus-branch] handle namespace scope David Carlton
@ 2002-11-21  9:40 ` Daniel Jacobowitz
  2002-11-21 12:29   ` David Carlton
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2002-11-21  9:40 UTC (permalink / raw)
  To: David Carlton; +Cc: gdb-patches

On Tue, Nov 19, 2002 at 03:07:45PM -0800, David Carlton wrote:
> Here are some patches for drow-cplus-branch that teach lookup_symbol
> and buildsym.c about the concept of "namespace scope".  Basically, if
> you have a function like this
> 
> namespace A
> {
>   void foo ()
>   {
>     // body of foo
>   }
> }
> 
> then, when doing name lookup within A::foo, when you hit the part
> where you'd normally search the global environment, you first search
> namespace A and then search the global namespace.  My previous patches
> had faked this by behaving as if there were a using directive "using
> namespace A;" at the start of the body of foo; this patch does it
> right.
> 
> One side effect of this is that struct block now has to have room for
> the current namespace as well as the current using directives; I
> decided to implement this in such a way as to use a little more memory
> in the C++ case but a little less memory in the non-C++ case.  (This
> also lead to a bunch of block accessor functions; I put them in
> symtab.{c,h}, but the block stuff should really be in block.{c,h}.
> I've done that on my branch, but I won't worry about that in
> drow-cplus-branch until it's that way on the mainline.)
> 
> There's also a little bit of futzing around with lookup_symbol_aux, to
> treat minsyms in a better way than I treated them in my last patch.  I
> didn't include the patch from
> <http://sources.redhat.com/ml/gdb-patches/2002-11/msg00378.html> that
> moves the field_of_this check to the right place, since that's
> somewhat orthogonal to this issue, but if you want I can include that
> as well.
> 
> This should get everything important out of the way before I start
> trying to add symbols associated to namespaces...
> 
> Okay to commit?

The idea is sound, some nits...

> @@ -485,21 +483,36 @@ finish_block (struct symbol *symbol, str
>  	  const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
>  	  const char *next;
>  
> -	  for (next = cp_find_first_component (name);
> -	       *next == ':';
> -	       /* The '+ 2' is to skip the '::'.  */
> -	       next = cp_find_first_component (next + 2))
> +if (processing_has_namespace_info)

Mailer/patch glitch?  Careful of your indentation.

> +	    block_set_scope (block, processing_current_namespace,
> +			     &objfile->symbol_obstack);
> +	  else
>  	    {
> -	      BLOCK_USING (block)
> -		= cp_add_using_obstack (name, 0, next - name,
> -					BLOCK_USING (block),
> -					&objfile->symbol_obstack);
> -	    }
> +	      const char *current, *next;
>  
> -	  /* FIMXE: carlton/2002-10-09: Until I understand the
> -	     possible pitfalls of demangled names a lot better, I want
> -	     to make sure I'm not running into surprises.  */
> -	  gdb_assert (*next == '\0');
> +	      /* FIXME: carlton/2002-11-14: For members of classes,
> +		 with this include the class name as well?  I don't
> +		 think that's a problem yet, but it will be.  */
> +	      
> +	      for (current = name, next = cp_find_first_component (current);
> +		   *next == ':';
> +		   /* The '+ 2' is to skip the '::'.  */
> +		   current = next,
> +		     next = cp_find_first_component (current + 2))
> +		;

I see that you're just moving this bit but I should have commented on
it last time: please do not use for loops this way.  Something like:
  current = name;
  next = cp_find_first_component (current);
  while (*next == ':')
    {
      current = next;
      /* The '+ 2' is to skip the '::'.  */
      *next = cp_find_first_component (current + 2);
    }

In general, if all the work is inside the parentheses a for loop is
inappropriate.

I did not extensively examine your lookup_symbol_* changes in this
patch; I eyeballed them and they looked good but that's it.  That's
enough for me while you're still evolving this.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [drow-cplus-branch] handle namespace scope
  2002-11-21  9:40 ` Daniel Jacobowitz
@ 2002-11-21 12:29   ` David Carlton
  2002-11-22  9:18     ` David Carlton
  0 siblings, 1 reply; 4+ messages in thread
From: David Carlton @ 2002-11-21 12:29 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

On Thu, 21 Nov 2002 12:40:10 -0500, Daniel Jacobowitz <drow@mvista.com> said:
> On Tue, Nov 19, 2002 at 03:07:45PM -0800, David Carlton wrote:

>> Okay to commit?

> The idea is sound, some nits...

>> @@ -485,21 +483,36 @@ finish_block (struct symbol *symbol, str
>> const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
>> const char *next;
>> 
>> -	  for (next = cp_find_first_component (name);
>> -	       *next == ':';
>> -	       /* The '+ 2' is to skip the '::'.  */
>> -	       next = cp_find_first_component (next + 2))
>> +if (processing_has_namespace_info)

> Mailer/patch glitch?  Careful of your indentation.

Whoops, thanks, that was a cut/paste problem.  Sorry about that.

>> +	      for (current = name, next = cp_find_first_component (current);
>> +		   *next == ':';
>> +		   /* The '+ 2' is to skip the '::'.  */
>> +		   current = next,
>> +		     next = cp_find_first_component (current + 2))
>> +		;

> I see that you're just moving this bit but I should have commented on
> it last time: please do not use for loops this way.  Something like:
>   current = name;
>   next = cp_find_first_component (current);
>   while (*next == ':')
>     {
>       current = next;
>       /* The '+ 2' is to skip the '::'.  */
>       *next = cp_find_first_component (current + 2);
>     }

> In general, if all the work is inside the parentheses a for loop is
> inappropriate.

Will do; that's probably not the only place I should fix this.

> I did not extensively examine your lookup_symbol_* changes in this
> patch; I eyeballed them and they looked good but that's it.  That's
> enough for me while you're still evolving this.

Great, thanks.  Yeah, that really is in flux: I'm starting to
understand what the underlying conceptual issues are, but I still
haven't gotten those nailed down properly.  And even once I do have
them nailed down properly, there are implementations details: e.g. the
lookup_symbol stuff does too much temporary allocation of copies via
xmalloc, which I suspect I'll want to eventually replace either by
temporary allocation on an obstack (or via alloca, maybe), or else
rewrite the code so that it doesn't need to make copies at all.

I'll commit it with the two fixes you mentioned, and I'll also look
for other loops that I should rewrite for clarity before committing.

Thanks,
David Carlton
carlton@math.stanford.edu


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [drow-cplus-branch] handle namespace scope
  2002-11-21 12:29   ` David Carlton
@ 2002-11-22  9:18     ` David Carlton
  0 siblings, 0 replies; 4+ messages in thread
From: David Carlton @ 2002-11-22  9:18 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

On 21 Nov 2002 12:29:43 -0800, David Carlton <carlton@math.Stanford.EDU> said:

> I'll commit it with the two fixes you mentioned, and I'll also look
> for other loops that I should rewrite for clarity before committing.

Commited; I found one other such loop (in
scan_for_anonymous_namespaces), and I also included a fix for
scan_partial_symbols in dwarf2read.c that handles anonymous namespaces
properly.  The actual patch I committed is below.

David Carlton
carlton@math.stanford.edu

2002-11-22  David Carlton  <carlton@math.stanford.edu>

	* symtab.h: Add opaque declarations for struct namespace_info and
	struct obstack.
	(struct block): The language_specific stuff is now a struct
	namespace_info rather than a struct using_direct_node.
	(BLOCK_NAMESPACE): New macro.
	Delete macro BLOCK_USING.
	Add declarations for block_using, block_all_usings,
	block_set_using, block_scope, block_set_scope.
	* symtab.c: #include "gdb_assert.h"
	(lookup_symbol_aux): Move minsym stuff inside
	lookup_symbol_aux_nonlocal, and always do global search via
	lookup_symbol_aux_using.
	(lookup_symbol_aux_nonlocal): Do minsym search.
	(lookup_symbol_aux_using): Calculate usings via block_all_usings;
	handle namespace scope.
	(lookup_symbol_aux_using_loop): New function, not to be confused
	with the previous function of the same name.  (Sorry about that.)
	(lookup_symbol_namespace): Renamed from
	lookup_symbol_aux_using_loop.
	(lookup_symbol_aux_minsyms): Add block_index argument, delete
	is_a_field_of_this argument, and only check either global or
	static symbols rather than both of them.
	(block_using): New function.
	(block_all_usings): New function.
	(block_set_using): New function.
	(block_scope): New function.
	(block_set_scope): New function.
	(block_initialize_namespace): New function.
	* jv-lang.c (get_java_class_symtab): BLOCK_NAMESPACE instead of
	BLOCK_USING.
	* dwarf2read.c: Delete variable current_namespace, and replace its
	uses by processing_current_namespace (from buildsym.h).
	(scan_partial_symbols): Allow empty pdi.name if we're
	reading a namespace.
	* cp-support.h (struct namespace_info): New struct.
	* cp-support.c: Add comment.
	* buildsym.h: New variable processing_current_namespace.
	* buildsym.c (add_symbol_to_list): Do fast search for
	"(anonymous namespace)".
	(scan_for_anonymous_namespaces): Delete FIXME.  Convert for loop
	into a clearer while loop.
	(finish_block): Replace BLOCK_USING by BLOCK_NAMESPACE.
	(finish_block): Set block_scope of function blocks rather than
	generating using directives that would have a similar effect.
	(end_symtab): Set using via block_set_using rather than
	BLOCK_USING.
	* Makefile.in (symtab.o): Depend on gdb_assert_h.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.268.2.2
diff -u -p -r1.268.2.2 Makefile.in
--- Makefile.in	26 Oct 2002 17:12:03 -0000	1.268.2.2
+++ Makefile.in	19 Nov 2002 22:35:53 -0000
@@ -2206,7 +2206,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h)
 	$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
 	$(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
 	$(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
-	$(cp_abi_h) $(source_h) $(cp_support_h)
+	$(cp_abi_h) $(source_h) $(cp_support_h) $(gdb_assert_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h)
Index: buildsym.c
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.c,v
retrieving revision 1.20.4.1
diff -u -p -r1.20.4.1 buildsym.c
--- buildsym.c	22 Oct 2002 19:59:36 -0000	1.20.4.1
+++ buildsym.c	19 Nov 2002 22:35:53 -0000
@@ -160,7 +160,9 @@ add_symbol_to_list (struct symbol *symbo
   
    if (SYMBOL_LANGUAGE (symbol) == language_cplus
        && !processing_has_namespace_info
-       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
+       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL
+       && strstr (SYMBOL_CPLUS_DEMANGLED_NAME (symbol),
+		  "(anonymous namespace)") != NULL)
      scan_for_anonymous_namespaces (symbol);
 }
 
@@ -177,10 +179,6 @@ scan_for_anonymous_namespaces (struct sy
   const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
   const char *beginning, *end;
 
-  /* FIXME: carlton/2002-10-14: Should we do some sort of fast search
-     first to see if the substring "(anonymous namespace)" occurs in
-     name at all?  */
-
   for (beginning = name, end = cp_find_first_component (name);
        *end == ':';
        /* The "+ 2" is for the "::"-.  */
@@ -384,7 +382,7 @@ finish_block (struct symbol *symbol, str
   BLOCK_END (block) = end;
   /* Superblock filled in when containing block is made */
   BLOCK_SUPERBLOCK (block) = NULL;
-  BLOCK_USING (block) = NULL;
+  BLOCK_NAMESPACE (block) = NULL;
 
   BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
 
@@ -485,21 +483,36 @@ finish_block (struct symbol *symbol, str
 	  const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
 	  const char *next;
 
-	  for (next = cp_find_first_component (name);
-	       *next == ':';
-	       /* The '+ 2' is to skip the '::'.  */
-	       next = cp_find_first_component (next + 2))
+if (processing_has_namespace_info)
+	    block_set_scope (block, processing_current_namespace,
+			     &objfile->symbol_obstack);
+	  else
 	    {
-	      BLOCK_USING (block)
-		= cp_add_using_obstack (name, 0, next - name,
-					BLOCK_USING (block),
-					&objfile->symbol_obstack);
-	    }
+	      const char *current, *next;
 
-	  /* FIMXE: carlton/2002-10-09: Until I understand the
-	     possible pitfalls of demangled names a lot better, I want
-	     to make sure I'm not running into surprises.  */
-	  gdb_assert (*next == '\0');
+	      /* FIXME: carlton/2002-11-14: For members of classes,
+		 with this include the class name as well?  I don't
+		 think that's a problem yet, but it will be.  */
+	      
+	      for (current = name, next = cp_find_first_component (current);
+		   *next == ':';
+		   /* The '+ 2' is to skip the '::'.  */
+		   current = next,
+		     next = cp_find_first_component (current + 2))
+		;
+	      if (current == name)
+		block_set_scope (block, "", &objfile->symbol_obstack);
+	      else
+		block_set_scope (block,
+				 obsavestring (name, current - name,
+					       &objfile->symbol_obstack),
+				 &objfile->symbol_obstack);
+	      
+	      /* FIXME: carlton/2002-10-09: Until I understand the
+		 possible pitfalls of demangled names a lot better, I
+		 want to make sure I'm not running into surprises.  */
+	      gdb_assert (*next == '\0');
+	    }
 	}
     }
   else
@@ -1063,9 +1076,10 @@ end_symtab (CORE_ADDR end_addr, struct o
       blockvector = make_blockvector (objfile);
       if (using_list != NULL)
 	{
-	  BLOCK_USING (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK))
-	    = copy_usings_to_obstack (using_list,
-				      &objfile->symbol_obstack);
+	  block_set_using (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
+			   copy_usings_to_obstack (using_list,
+						   &objfile->symbol_obstack),
+			   &objfile->symbol_obstack);
 	  using_list = NULL;
 	}
     }
Index: buildsym.h
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.h,v
retrieving revision 1.5.10.1
diff -u -p -r1.5.10.1 buildsym.h
--- buildsym.h	22 Oct 2002 19:59:36 -0000	1.5.10.1
+++ buildsym.h	19 Nov 2002 22:35:53 -0000
@@ -99,6 +99,13 @@ EXTERN unsigned char processing_hp_compi
 
 EXTERN unsigned char processing_has_namespace_info;
 
+/* If processing_has_namespace_info is nonzero, this string should
+   contain the name of the current namespace.  Other people shouldn't
+   have to copy it when referring to it, so don't free its previous
+   contents when setting this to a new value.  */
+
+EXTERN const char *processing_current_namespace;
+
 /* Count symbols as they are processed, for error messages.  */
 
 EXTERN unsigned int symnum;
Index: cp-support.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.c,v
retrieving revision 1.1.6.1
diff -u -p -r1.1.6.1 cp-support.c
--- cp-support.c	22 Oct 2002 19:59:36 -0000	1.1.6.1
+++ cp-support.c	19 Nov 2002 22:35:53 -0000
@@ -52,6 +52,12 @@
      fairly restrictive set of locations (in particular, they have be
      at depth 0, don't they?).  */
 
+/* NOTE: carlton/2002-10-25: Daniel Jacobowitz came up with an example
+   where operator names don't occur at depth 0.  Sigh.  (It involved a
+   template argument that was a pointer: I hadn't realized that was
+   possible.)  Handling such edge cases does not seem like a
+   high-priority problem to me.  */
+
 /* FIXME: carlton/2002-10-09: Do all the functions here handle all the
    above considerations correctly?  */
 
Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.1.6.1
diff -u -p -r1.1.6.1 cp-support.h
--- cp-support.h	22 Oct 2002 19:59:36 -0000	1.1.6.1
+++ cp-support.h	19 Nov 2002 22:35:53 -0000
@@ -67,6 +67,16 @@ struct using_direct_node
   struct using_direct_node *next;
 };
 
+/* This is used by struct block to store namespace-related info for
+   C++ files, namely using declarations and the current namespace in
+   scope.  */
+
+struct namespace_info
+{
+  struct using_direct_node *using;
+  const char *scope;
+};
+
 extern struct
 using_direct_node *cp_add_using_obstack (const char *name,
 					 unsigned short outer_length,
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.67.2.2
diff -u -p -r1.67.2.2 dwarf2read.c
--- dwarf2read.c	26 Oct 2002 17:12:06 -0000	1.67.2.2
+++ dwarf2read.c	19 Nov 2002 22:35:54 -0000
@@ -388,13 +388,6 @@ static struct partial_die_info zeroed_pa
    in buildsym.c.  */
 static struct pending **list_in_scope = &file_symbols;
 
-/* If we're debugging C++ code, this string should contain the name of
-   the current namespace.  Other people shouldn't have to copy it when
-   referring to it, so don't free its previous contents when setting
-   this to a new value.  */
-
-static const char *current_namespace;
-
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
@@ -1632,7 +1625,7 @@ psymtab_to_symtab_1 (struct partial_symt
   info_ptr = dwarf_info_buffer + offset;
 
   /* We're in the global namespace.  */
-  current_namespace = "";
+  processing_current_namespace = "";
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -2998,7 +2991,7 @@ static void
 read_namespace (struct die_info *die, struct objfile *objfile,
 		const struct comp_unit_head *cu_header)
 {
-  const char *previous_namespace = current_namespace;
+  const char *previous_namespace = processing_current_namespace;
   const char *name = NULL;
   int is_anonymous;
   struct die_info *current_die;
@@ -3021,18 +3014,19 @@ read_namespace (struct die_info *die, st
 
   /* Now build the name of the current namespace.  */
 
-  current_namespace = obconcat (&objfile->symbol_obstack,
-				previous_namespace,
-				previous_namespace[0] == '\0' ? "" : "::",
-				name);
+  processing_current_namespace = obconcat (&objfile->symbol_obstack,
+					   previous_namespace,
+					   previous_namespace[0] == '\0'
+					   ? "" : "::",
+					   name);
 
   /* If it's an anonymous namespace that we're seeing for the first
      time, add a using directive.  */
 
   if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
-    add_using_directive (current_namespace,
+    add_using_directive (processing_current_namespace,
 			 strlen (previous_namespace),
-			 strlen (current_namespace));
+			 strlen (processing_current_namespace));
   
   
   if (die->has_children)
@@ -3046,7 +3040,7 @@ read_namespace (struct die_info *die, st
 	}
     }
 
-  current_namespace = previous_namespace;
+  processing_current_namespace = previous_namespace;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
Index: jv-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-lang.c,v
retrieving revision 1.12.10.1
diff -u -p -r1.12.10.1 jv-lang.c
--- jv-lang.c	22 Oct 2002 19:59:36 -0000	1.12.10.1
+++ jv-lang.c	19 Nov 2002 22:35:54 -0000
@@ -111,7 +111,7 @@ get_java_class_symtab (void)
       BLOCK_END (bl) = 0;
       BLOCK_FUNCTION (bl) = NULL;
       BLOCK_SUPERBLOCK (bl) = NULL;
-      BLOCK_USING (bl) = NULL;
+      BLOCK_NAMESPACE (bl) = NULL;
       BLOCK_GCC_COMPILED (bl) = 0;
       BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
 
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.70.4.3
diff -u -p -r1.70.4.3 symtab.c
--- symtab.c	26 Oct 2002 17:12:09 -0000	1.70.4.3
+++ symtab.c	19 Nov 2002 22:35:54 -0000
@@ -50,6 +50,7 @@
 #include <ctype.h>
 #include "cp-abi.h"
 #include "cp-support.h"
+#include "gdb_assert.h"
 
 /* Prototypes for local functions */
 
@@ -119,22 +120,30 @@ struct symbol *lookup_symbol_aux_using (
 					struct symtab **symtab);
 
 static
-struct symbol *lookup_symbol_aux_using_loop (const char *prefix,
-					     int prefix_len,
-					     const char *rest,
-					     struct using_direct_node *using,
+struct symbol *lookup_symbol_aux_using_loop (const char *name,
 					     const char *mangled_name,
 					     namespace_enum namespace,
-					     struct symtab **symtab);
+					     struct symtab **symtab,
+					     const char *scope,
+					     int scope_len,
+					     struct using_direct_node *using);
 
 static
-struct symbol *lookup_symbol_aux_minsyms (const char *name,
+struct symbol *lookup_symbol_namespace (const char *prefix,
+					int prefix_len,
+					const char *rest,
+					struct using_direct_node *using,
+					const char *mangled_name,
+					namespace_enum namespace,
+					struct symtab **symtab);
+
+static
+struct symbol *lookup_symbol_aux_minsyms (int block_index,
+					  const char *name,
 					  const char *mangled_name,
 					  const namespace_enum namespace,
-					  int *is_a_field_of_this,
 					  struct symtab **symtab);
 
-
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
 
 /* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
@@ -154,6 +163,9 @@ static void symtab_symbol_info (char *, 
 
 static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
 
+static void block_initialize_namespace (struct block *block,
+					struct obstack *obstack);
+
 void _initialize_symtab (void);
 
 /* */
@@ -842,84 +854,35 @@ lookup_symbol_aux (const char *name, con
 	}
     }
 
-  /* Now search all global blocks.  Do the symtab's first, then
-     check the psymtab's. If a psymtab indicates the existence
-     of the desired name as a global, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
-
-  sym = lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, name, mangled_name,
-				    namespace, symtab);
-  if (sym != NULL)
-    return sym;
-
-  /* If we're in the C++ case, check to see if the symbol is defined
-     in a namespace accessible via a "using" declaration.  */
-
-  /* FIXME: carlton/2002-10-10: is "is_a_field_of_this" always
-     non-NULL if we're in the C++ case?  Maybe we should always do
-     this, and delete the two previous searches: this will always
-     search the global namespace, after all.  */
-
-  if (is_a_field_of_this)
-    {
-      sym = lookup_symbol_aux_using (name, mangled_name, block, namespace,
-				     symtab);
-      if (sym != NULL)
-	return sym;
-    }
-
-#ifndef HPUXHPPA
+  /* Now search all global blocks.  Do the symtab's first, then the
+     minsyms, then check the psymtab's. If minsyms or psymtabs
+     indicate the existence of the desired name as a global, then
+     generate the appropriate symtab on the fly and return the found
+     symbol.
+
+     We do this from within lookup_symbol_aux_using: that will apply
+     appropriate using directives in the C++ case.  But it works fine
+     in the non-C++ case, too.  */
+
+  /* NOTE: carlton/2002-10-22: Is it worthwhile to try to figure out
+     whether or not we're in the C++ case?  Doing
+     lookup_symbol_aux_using won't slow things down significantly in
+     the general case, though: other parts of this function are much,
+     much more expensive.  */
 
-  /* Check for the possibility of the symbol being a function or a
-     mangled variable that is stored in one of the minimal symbol
-     tables.  Eventually, all global symbols might be resolved in this
-     way.  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-				   namespace, is_a_field_of_this,
-				   symtab);
+  sym = lookup_symbol_aux_using (name, mangled_name, block, namespace,
+				 symtab);
   if (sym != NULL)
     return sym;
 
-#endif
-
   /* Now search all static file-level symbols.  Not strictly correct,
-     but more useful than an error.  Do the symtabs first, then check
-     the psymtabs.  If a psymtab indicates the existence of the
-     desired name as a file-level static, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
+     but more useful than an error.  */
 
   sym = lookup_symbol_aux_nonlocal (STATIC_BLOCK, name, mangled_name,
 				    namespace, symtab);
   if (sym != NULL)
     return sym;
 
-#ifdef HPUXHPPA
-
-  /* Check for the possibility of the symbol being a function or a
-     global variable that is stored in one of the minimal symbol
-     tables.  The "minimal symbol table" is built from linker-supplied
-     info.
-
-     RT: I moved this check to last, after the complete search of the
-     global (p)symtab's and static (p)symtab's. For HP-generated
-     symbol tables, this check was causing a premature exit from
-     lookup_symbol with NULL return, and thus messing up symbol
-     lookups of things like "c::f". It seems to me a check of the
-     minimal symbol table ought to be a last resort in any case. I'm
-     vaguely worried about the comment within
-     lookup_symbol_aux_minsyms which talks about FORTRAN routines
-     "foo_" though... is it saying we need to do the "minsym" check
-     before the static check in this case?  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-				   namespace, is_a_field_of_this,
-				   symtab);
-  if (sym != NULL)
-    return sym;
-
-#endif
-
   if (symtab != NULL)
     *symtab = NULL;
   return NULL;
@@ -975,9 +938,6 @@ lookup_symbol_aux_local (const char *nam
    STATIC_BLOCK, depending on whether or not we want to search global
    symbols or static symbols.  */
 
-/* FIXME: carlton/2002-10-11: Should this also do some minsym
-   lookup?  */
-
 static struct symbol *
 lookup_symbol_aux_nonlocal (int block_index,
 			    const char *name,
@@ -992,8 +952,63 @@ lookup_symbol_aux_nonlocal (int block_in
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (block_index, name, mangled_name,
-				     namespace, symtab);
+#ifndef HPUXHPPA
+  sym = lookup_symbol_aux_minsyms (block_index, name, mangled_name,
+				   namespace, symtab);
+  if (sym != NULL)
+    return sym;
+#endif
+
+  sym = lookup_symbol_aux_psymtabs (block_index, name, mangled_name,
+				    namespace, symtab);
+  if (sym != NULL)
+    return sym;
+
+#ifdef HPUXHPPA
+
+  /* FIXME: carlton/2002-10-28: The following comment was present in
+     lookup_symbol_aux before I broke it up: at that time, the HP
+     search order for nonlocal stuff was global symtab, global
+     psymtab, static symtab, static psymtab, global and static
+     minsyms.  (The minsyms are stored so that it's just as easy to do
+     global and static searches of them at the same time.)  Now it's
+     global symtab, global psymtab, global minsyms, static symtab,
+     static psymtab, static minsyms.  Also, it's now impossible for a
+     global minsym search to cause a NULL return by itself: if a
+     minsym search returns NULL, then the next search after that is
+     still performed.
+
+     Given that that's the case, I'm pretty sure that my search order
+     is safe; indeed, given that the comment below warns against
+     premature NULL returns, it even seems plausible to me that we can
+     treat HP symbol tables the same as non-HP symbol tables.  It
+     would be great if somebody who has access to HP machines (or,
+     even better, who understands the reason behind the HP special
+     case in the first place) could check on this.
+
+     But there's still the comment about "foo_" symbols in
+     lookup_symbol_aux_minsyms which I really don't understand, sigh.
+     _Should_ a minsym lookup sometimes be able to force a NULL return
+     from lookup_symbol?  */
+
+  /* RT: I moved this check to last, after the complete search of the
+     global (p)symtab's and static (p)symtab's. For HP-generated
+     symbol tables, this check was causing a premature exit from
+     lookup_symbol with NULL return, and thus messing up symbol
+     lookups of things like "c::f". It seems to me a check of the
+     minimal symbol table ought to be a last resort in any case. I'm
+     vaguely worried about the comment within
+     lookup_symbol_aux_minsyms which talks about FORTRAN routines
+     "foo_" though... is it saying we need to do the "minsym" check
+     before the static check in this case?  */
+
+  sym = lookup_symbol_aux_minsyms (block_index, name, mangled_name,
+				   namespace, symtab);
+  if (sym != NULL)
+    return sym;
+#endif
+
+  return NULL;
 }
 
 /* Check to see if the symbol is defined in one of the symtabs.
@@ -1092,32 +1107,69 @@ lookup_symbol_aux_psymtabs (int block_in
 /* This function gathers using directives from BLOCK and its
    superblocks, and then searches for symbols in the global namespace
    by trying to apply those various using directives.  */
+
 static struct symbol *lookup_symbol_aux_using (const char *name,
 					       const char *mangled_name,
 					       const struct block *block,
 					       const namespace_enum namespace,
 					       struct symtab **symtab)
 {
-  struct using_direct_node *using = NULL;
+  struct using_direct_node *using;
+  const char *scope;
   struct symbol *sym;
 
-  while (block != NULL)
-    {
-      using = cp_copy_usings (BLOCK_USING (block), using);
-      block = BLOCK_SUPERBLOCK (block);
-    }
-
-  sym = lookup_symbol_aux_using_loop ("", 0, name, using, mangled_name,
-				      namespace, symtab);
+  using = block_all_usings (block);
+  scope = block_scope (block);
+  
+  sym = lookup_symbol_aux_using_loop (name, mangled_name, namespace, symtab,
+				      scope, 0, using);
   cp_free_usings (using);
   
   return sym;
 }
 
+/* Look up NAME in the namespaces given by SCOPE and its initial
+   prefixes, applying using directives given by USING; only consider
+   prefixes that are at least as long as SCOPE_LEN, however.  Look up
+   longest prefixes first.  */
+
+static struct
+symbol *lookup_symbol_aux_using_loop (const char *name,
+				      const char *mangled_name,
+				      namespace_enum namespace,
+				      struct symtab **symtab,
+				      const char *scope,
+				      int scope_len,
+				      struct using_direct_node *using)
+{
+  if (scope[scope_len] != '\0')
+    {
+      struct symbol *sym;
+      int next_component;
+      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;
+	}
+      next_component = cp_find_first_component (scope + new_scope_len) - scope;
+      sym = lookup_symbol_aux_using_loop (name, mangled_name, namespace,
+					  symtab, scope, next_component,
+					  using);
+      if (sym != NULL)
+	return sym;
+    }
+
+  return lookup_symbol_namespace (scope, scope_len, name, using,
+				  mangled_name, namespace, symtab);
+}
+
 /* This tries to look up REST in the namespace given by the initial
    substring of PREFIX of length PREFIX_LEN.
 
-   Basically, assume that we have using directives adding A to the
+   For example, assume that we have using directives adding A to the
    global namespace, adding A::inner to namespace A, and adding B to
    the global namespace.  Then, when looking up a symbol "foo", we
    want to recurse by looking up stuff in A::foo and seeing which
@@ -1138,14 +1190,19 @@ static struct symbol *lookup_symbol_aux_
    namespaces first-class objects.  (Which is certainly a good idea
    for other reasons, but it will take a little while.)  */
 
+/* NOTE: carlton/2002-11-19: This is optimistically called
+   lookup_symbol_namespace instead of lookup_symbol_aux_namespace in
+   hopes that it or something like it might eventually be useful
+   outside of lookup_symbol.  */
+
 static struct symbol *
-lookup_symbol_aux_using_loop (const char *prefix,
-			      int prefix_len,
-			      const char *rest,
-			      struct using_direct_node *using,
-			      const char *mangled_name,
-			      namespace_enum namespace,
-			      struct symtab **symtab)
+lookup_symbol_namespace (const char *prefix,
+			 int prefix_len,
+			 const char *rest,
+			 struct using_direct_node *using,
+			 const char *mangled_name,
+			 namespace_enum namespace,
+			 struct symtab **symtab)
 {
   struct using_direct_node *current;
   struct symbol *sym;
@@ -1179,14 +1236,13 @@ lookup_symbol_aux_using_loop (const char
 	      if (*new_rest == ':')
 		new_rest += 2;
 
-	      sym = lookup_symbol_aux_using_loop
-		(current->current->name,
-		 current->current->inner_length,
-		 new_rest,
-		 using,
-		 mangled_name,
-		 namespace,
-		 symtab);
+	      sym = lookup_symbol_namespace (current->current->name,
+					     current->current->inner_length,
+					     new_rest,
+					     using,
+					     mangled_name,
+					     namespace,
+					     symtab);
 	      if (sym != NULL)
 		return sym;
 	    }
@@ -1223,10 +1279,9 @@ lookup_symbol_aux_using_loop (const char
    way.  */
 
 static struct symbol *
-lookup_symbol_aux_minsyms (const char *name,
+lookup_symbol_aux_minsyms (int block_index, const char *name,
 			   const char *mangled_name,
 			   const namespace_enum namespace,
-			   int *is_a_field_of_this,
 			   struct symtab **symtab)
 {
   struct symbol *sym;
@@ -1250,7 +1305,30 @@ lookup_symbol_aux_minsyms (const char *n
 	     know about demangled names, but we were given a mangled
 	     name...  */
 
-	  /* We first use the address in the msymbol to try to locate
+	  /* First, check to see that the symbol looks like it's
+	     global or static (depending on what we were asked to look
+	     for).  */
+
+	  /* NOTE: carlton/2002-10-28: lookup_minimal_symbol gives
+	     preference to global symbols over static symbols, so if
+	     block_index is STATIC_BLOCK then this might well miss
+	     static symbols that are shadowed by global symbols.  But
+	     that's okay: this is only called with block_index equal
+	     to STATIC_BLOCK if a global search has failed.  */
+
+	  switch (MSYMBOL_TYPE (msymbol))
+	    {
+	    case mst_file_text:
+	    case mst_file_data:
+	    case mst_file_bss:
+	      if (block_index == GLOBAL_BLOCK)
+		return NULL;
+	    default:
+	      if (block_index == STATIC_BLOCK)
+		return NULL;
+	    }
+	  
+	  /* We next use the address in the msymbol to try to locate
 	     the appropriate symtab. Note that find_pc_sect_symtab()
 	     has a side-effect of doing psymtab-to-symtab expansion,
 	     for the found symtab.  */
@@ -1260,7 +1338,7 @@ lookup_symbol_aux_minsyms (const char *n
 	    {
 	      /* This is a function which has a symtab for its address.  */
 	      bv = BLOCKVECTOR (s);
-	      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+	      block = BLOCKVECTOR_BLOCK (bv, block_index);
 
 	      /* This call used to pass `SYMBOL_NAME (msymbol)' as the
 	         `name' argument to lookup_block_symbol.  But the name
@@ -1269,14 +1347,16 @@ lookup_symbol_aux_minsyms (const char *n
 	         unmangled name.  */
 	      sym =
 		lookup_block_symbol (block, name, mangled_name, namespace);
-	      /* We kept static functions in minimal symbol table as well as
-	         in static scope. We want to find them in the symbol table. */
-	      if (!sym)
-		{
-		  block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-		  sym = lookup_block_symbol (block, name,
-					     mangled_name, namespace);
-		}
+
+	      /* FIXME: carlton/2002-10-28: this next comment dates
+		 from when this code was part of lookup_symbol_aux, so
+		 this return could return NULL from lookup_symbol_aux.
+		 Are there really situations where we want a minimal
+		 symbol lookup to be able to force a NULL return from
+		 lookup_symbol?  If so, maybe the thing to do would be
+		 to have lookup_symbol_aux_minsym to set a
+		 minsym_found flag, and to have lookup_symbol_aux only
+		 do the psymtab search if that flag is zero.  */
 
 	      /* sym == 0 if symbol was found in the minimal symbol table
 	         but not in the symtab.
@@ -1297,13 +1377,15 @@ lookup_symbol_aux_minsyms (const char *n
 	    }
 	  else if (MSYMBOL_TYPE (msymbol) != mst_text
 		   && MSYMBOL_TYPE (msymbol) != mst_file_text
-		   && !STREQ (name, SYMBOL_NAME (msymbol)))
+		   && strcmp (name, SYMBOL_NAME (msymbol)) != 0)
 	    {
 	      /* This is a mangled variable, look it up by its
 	         mangled name.  */
-	      return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
-					NULL, namespace, is_a_field_of_this,
-					symtab);
+	      return lookup_symbol_aux_nonlocal (block_index,
+						 SYMBOL_NAME (msymbol),
+						 mangled_name,
+						 namespace,
+						 symtab);
 	    }
 	}
     }
@@ -3275,6 +3357,96 @@ contained_in (struct block *a, struct bl
   return BLOCK_START (a) >= BLOCK_START (b)
     && BLOCK_END (a) <= BLOCK_END (b);
 }
+
+/* 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 using directives associated to BLOCK (but _not_
+   its parents), if any.  */
+
+struct using_direct_node *
+block_using (const struct block *block)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    return NULL;
+  else
+    return BLOCK_NAMESPACE (block)->using;
+}
+
+/* This returns the using directives associated to BLOCK and its
+   parents, if any.  The resulting structure must be freed by calling
+   cp_free_usings on it.  */
+
+struct using_direct_node *
+block_all_usings (const struct block *block)
+{
+  struct using_direct_node *using = NULL;
+
+  while (block != NULL)
+    {
+      using = cp_copy_usings (block_using (block), using);
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  return using;
+}
+
+/* Set block_using (BLOCK) to USING; if needed, allocate memory via
+   OBSTACK.  */
+
+void
+block_set_using (struct block *block, struct using_direct_node *using,
+		 struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->using = using;
+}
+
+/* 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_scope (BLOCK) to SCOPE; if needed, allocate memory via
+   OBSTACK.  (It won't make a copy of SCOPE, however, so that already
+   has to be allocated correctly.)  */
+
+void
+block_set_scope (struct block *block, const char *scope,
+		 struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->scope = scope;
+}
+
+/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
+   ititialize its members to zero.  */
+
+static void
+block_initialize_namespace (struct block *block, struct obstack *obstack)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    {
+      BLOCK_NAMESPACE (block)
+	= obstack_alloc (obstack, sizeof (struct namespace_info));
+      BLOCK_NAMESPACE (block)->using = NULL;
+    }
+}
+
 \f
 
 /* Helper routine for make_symbol_completion_list.  */
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.42.4.2
diff -u -p -r1.42.4.2 symtab.h
--- symtab.h	26 Oct 2002 17:12:09 -0000	1.42.4.2
+++ symtab.h	19 Nov 2002 22:35:54 -0000
@@ -25,7 +25,9 @@
 
 /* Opaque declarations.  */
 struct obstack;
+struct namespace_info;
 struct using_direct_node;
+struct obstack;
 
 /* Don't do this; it means that if some .o's are compiled with GNU C
    and some are not (easy to do accidentally the way we configure
@@ -374,12 +376,11 @@ struct block
   {
     struct
     {
-      /* Contains information about what using directives or other
-	 similar features are added by this block.  This should always
-	 be NULL for global blocks: if there are using directives that
-	 affect an entire file, put it in the static block.  */
+      /* Contains information about namespace-related info relevant to
+	 this block: using directives and the current namespace
+	 scope.  */
       
-      struct using_direct_node *using;
+      struct namespace_info *namespace;
     }
     cplus_specific;
   }
@@ -430,7 +431,7 @@ struct block
 #define BLOCK_END(bl)		(bl)->endaddr
 #define BLOCK_FUNCTION(bl)	(bl)->function
 #define BLOCK_SUPERBLOCK(bl)	(bl)->superblock
-#define BLOCK_USING(bl)		(bl)->language_specific.cplus_specific.using
+#define BLOCK_NAMESPACE(bl)	(bl)->language_specific.cplus_specific.namespace
 #define BLOCK_GCC_COMPILED(bl)	(bl)->gcc_compile_flag
 #define BLOCK_HASHTABLE(bl)	(bl)->hashtable
 
@@ -1143,6 +1144,19 @@ extern struct partial_symbol *find_pc_se
 extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
 
 extern int contained_in (struct block *, struct block *);
+
+extern struct using_direct_node *block_using (const struct block *);
+
+extern struct using_direct_node *block_all_usings (const struct block *block);
+
+extern void block_set_using (struct block *block,
+			     struct using_direct_node *using,
+			     struct obstack *obstack);
+
+extern const char *block_scope (const struct block *block);
+
+extern void block_set_scope (struct block *block, const char *scope,
+			     struct obstack *obstack);
 
 extern void reread_symbols (void);
 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-11-22 17:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-19 15:07 [drow-cplus-branch] handle namespace scope David Carlton
2002-11-21  9:40 ` Daniel Jacobowitz
2002-11-21 12:29   ` David Carlton
2002-11-22  9:18     ` David Carlton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox