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]

[drow-cplus-branch] handle namespace scope


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;
+    }
+}
+
 
 
 /* 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);
 


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