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]

Re: [rfa] generate symbols associated to namespaces


David Carlton writes:
 > On Fri, 27 Jun 2003 09:04:13 -0700, David Carlton <carlton@kealia.com> said:
 > 
 > > I've looked at your code comments, and they all seem reasonable.  I
 > > hope I'll have a revised version of the patch today; job transition
 > > issues will take up some of my time (I start full-time work at
 > > Kealia today, so I have to figure out what they want me to do other
 > > than hack GDB), but it's near the top of my priority list.
 > 
 > Okay, here's the new version.  Following Daniel's suggestion, it puts
 > symbols associated to DW_TAG_namespace in the symtab where they are
 > found, instead of in a special block, and creates one possible
 > namespace block for each objfile.  This fixes the problem Daniel found
 > with the last version of my patch (which, incidentally, turns out also
 > to show up under DWARF 2 with pr-1210.exp; the more tests the
 > merrier).
 > 
 > Tested with GCC 3.2, i686-pc-linux-gnu with both DWARF 2 and stabs+,
 > and with a version of GCC 3.2.3 that generates DW_TAG_namespace DIEs.
 > No new regressions (though the new tests in gdb.c++/namespace.exp fail
 > under stabs+, as expected).
 > 
 > How does this one look to y'all?


It looks ok, but there are a couple of things I'd like to see addressed,
see below.

elena



 > 
 > David Carlton
 > carlton@kealia.com
 > 
 > 2003-06-27  David Carlton  <carlton@kealia.com>
 > 
 > 	* gdbtypes.h: Add TYPE_CODE_NAMESPACE.
 > 	* gdbtypes.c (init_type): Handle TYPE_CODE_NAMESPACE.
 > 	(recursive_dump_type): Ditto.
 > 	* printcmd.c (print_formatted): Ditto.
 > 	* typeprint.c (print_type_scalar): Ditto.
 > 	* c-typeprint.c (c_type_print_varspec_prefix): Ditto.
 > 	(c_type_print_varspec_suffix, c_type_print_base): Ditto.
 > 	* cp-support.h: Declare cp_check_possible_namespace_symbols,
 > 	maint_cplus_cmd_list.
 > 	* cp-support.c: Make maint_cplus_cmd_list extern.
 > 	* cp-namespace.c: Include objfiles.h, gdbtypes.h, dictionary.h,
 > 	command.h.
 > 	(lookup_symbol_file): Look in possible namespace blocks when
 > 	appropriate.
 > 	(initialize_namespace_symtab): New.
 > 	(get_possible_namespace_block, free_namespace_block)
 > 	(check_possible_namespace_symbols)
 > 	(check_possible_namespace_symbols_loop)
 > 	(check_one_possible_namespace_symbol)
 > 	(lookup_possible_namespace_symbol, maintenance_cplus_namespace)
 > 	(_initialize_cp_namespace): Ditto.
 > 	* block.h: Declare allocate_block.
 > 	* block.c (allocate_block): New.
 > 	* jv-lang.c (get_java_class_symtab): Allocate blocks via
 > 	allocate_block.
 > 	* symfile.h: Update declaration of add_psymbol_to_list.
 > 	* symfile.c (add_psymbol_to_list): Return the partial symbol in
 > 	question.
 > 	* dwarf2read.c (dwarf2_build_psymtabs_hard): Do initial setting
 > 	lowpc and highpc ourselves.  Add argument to
 > 	scan_partial_symbols_call.
 > 	(scan_partial_symbols): Restructure into a recursive version,
 > 	calling add_partial_namespace and add_partial_enumeration when
 > 	appropriate.
 > 	(add_partial_symbol): If necessary, scan mangled names for names
 > 	of namespaces.
 > 	(add_partial_namespace): New.
 > 	(add_partial_enumeration, locate_pdi_sibling): Ditto.
 > 	* objfiles.h (struct objfile): Add cp_namespace_symtab member.
 > 	* objfiles.c (allocate_objfile): Set
 > 	objfile->cp_namespace_symtab.
 > 	* Makefile.in (cp-namespace.o): Depend on objfiles_h, gdbtypes_h,
 > 	dictionary_h, command_h.
 > 
 > 2003-06-27  David Carlton  <carlton@kealia.com>
 > 
 > 	* gdb.c++/namespace.exp: Add tests for namespace types.
 > 	* gdb.c++/maint.exp (test_help): Test 'help maint cp namespace'.
 > 	(test_namespace): New.
 > 
 > Index: Makefile.in
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/Makefile.in,v
 > retrieving revision 1.410
 > diff -u -p -r1.410 Makefile.in
 > --- Makefile.in	21 Jun 2003 23:14:43 -0000	1.410
 > +++ Makefile.in	27 Jun 2003 21:37:38 -0000
 > @@ -1642,7 +1642,8 @@ corelow.o: corelow.c $(defs_h) $(gdb_str
 >  cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) \
 >  	$(gdbcmd_h) $(ui_out_h) $(gdb_string_h)
 >  cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_h) \
 > -	$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h)
 > +	$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h) $(objfiles_h) \
 > +	$(gdbtypes_h) $(dictionary_h) $(command_h)
 >  cp-support.o: cp-support.c $(defs_h) $(cp_support_h) $(gdb_string_h) \
 >  	$(demangle_h) $(gdb_assert_h) $(gdbcmd_h) $(dictionary_h) \
 >  	$(objfiles_h) $(frame_h) $(block_h)
 > Index: block.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/block.c,v
 > retrieving revision 1.7
 > diff -u -p -r1.7 block.c
 > --- block.c	2 Jun 2003 18:36:33 -0000	1.7
 > +++ block.c	27 Jun 2003 21:37:40 -0000
 > @@ -268,3 +268,28 @@ block_global_block (const struct block *
 >  
 >    return block;
 >  }
 > +
 > +/* Allocate a block on OBSTACK, and initialize its elements to
 > +   zero/NULL.  This is useful for creating "dummy" blocks that don't
 > +   correspond to actual source files.
 > +
 > +   Warning: it sets the block's BLOCK_DICT to NULL, which isn't a
 > +   valid value.  If you really don't want the block to have a
 > +   dictionary, then you should subsequently set its BLOCK_DICT to
 > +   dict_create_linear (obstack, NULL).  */
 > +
 > +struct block *
 > +allocate_block (struct obstack *obstack)
 > +{
 > +  struct block *bl = obstack_alloc (obstack, sizeof (struct block));
 > +
 > +  BLOCK_START (bl) = 0;
 > +  BLOCK_END (bl) = 0;
 > +  BLOCK_FUNCTION (bl) = NULL;
 > +  BLOCK_SUPERBLOCK (bl) = NULL;
 > +  BLOCK_DICT (bl) = NULL;
 > +  BLOCK_NAMESPACE (bl) = NULL;
 > +  BLOCK_GCC_COMPILED (bl) = 0;
 > +
 > +  return bl;
 > +}
 > Index: block.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/block.h,v
 > retrieving revision 1.8
 > diff -u -p -r1.8 block.h
 > --- block.h	11 Jun 2003 23:29:46 -0000	1.8
 > +++ block.h	27 Jun 2003 21:37:40 -0000
 > @@ -171,4 +171,6 @@ extern const struct block *block_static_
 >  
 >  extern const struct block *block_global_block (const struct block *block);
 >  
 > +extern struct block *allocate_block (struct obstack *obstack);
 > +
 >  #endif /* BLOCK_H */
 > Index: c-typeprint.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/c-typeprint.c,v
 > retrieving revision 1.26
 > diff -u -p -r1.26 c-typeprint.c
 > --- c-typeprint.c	4 Jan 2003 21:54:54 -0000	1.26
 > +++ c-typeprint.c	27 Jun 2003 21:37:58 -0000
 > @@ -284,6 +284,7 @@ c_type_print_varspec_prefix (struct type
 >      case TYPE_CODE_BITSTRING:
 >      case TYPE_CODE_COMPLEX:
 >      case TYPE_CODE_TEMPLATE:
 > +    case TYPE_CODE_NAMESPACE:
 >        /* These types need no prefix.  They are listed here so that
 >           gcc -Wall will reveal any types that haven't been handled.  */
 >        break;
 > @@ -624,6 +625,7 @@ c_type_print_varspec_suffix (struct type
 >      case TYPE_CODE_BITSTRING:
 >      case TYPE_CODE_COMPLEX:
 >      case TYPE_CODE_TEMPLATE:
 > +    case TYPE_CODE_NAMESPACE:
 >        /* These types do not need a suffix.  They are listed so that
 >           gcc -Wall will report types that may not have been considered.  */
 >        break;
 > @@ -1180,6 +1182,11 @@ c_type_print_base (struct type *type, st
 >  		fprintf_filtered (stream, "\n");
 >  	    }
 >  	}
 > +      break;
 > +
 > +    case TYPE_CODE_NAMESPACE:
 > +      fputs_filtered ("namespace ", stream);
 > +      fputs_filtered (TYPE_TAG_NAME (type), stream);
 >        break;
 >  
 >      default:
 > Index: cp-namespace.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/cp-namespace.c,v
 > retrieving revision 1.3
 > diff -u -p -r1.3 cp-namespace.c
 > --- cp-namespace.c	13 Jun 2003 00:55:43 -0000	1.3
 > +++ cp-namespace.c	27 Jun 2003 21:38:02 -0000
 > @@ -27,6 +27,10 @@
 >  #include "symfile.h"
 >  #include "gdb_assert.h"
 >  #include "block.h"
 > +#include "objfiles.h"
 > +#include "gdbtypes.h"
 > +#include "dictionary.h"
 > +#include "command.h"
 >  
 >  /* When set, the file that we're processing seems to have debugging
 >     info for C++ namespaces, so cp-namespace.c shouldn't try to guess
 > @@ -70,6 +74,26 @@ static struct symbol *lookup_symbol_file
 >  					  struct symtab **symtab,
 >  					  int anonymous_namespace);
 >  
 > +static void initialize_namespace_symtab (struct objfile *objfile);
 > +
 > +static struct block *get_possible_namespace_block (struct objfile *objfile);
 > +
 > +static void free_namespace_block (struct symtab *symtab);
 > +
 > +static int check_possible_namespace_symbols_loop (const char *name,
 > +						  int len,
 > +						  struct objfile *objfile);
 > +
 > +static int check_one_possible_namespace_symbol (const char *name,
 > +						int len,
 > +						struct objfile *objfile);
 > +
 > +static
 > +struct symbol *lookup_possible_namespace_symbol (const char *name,
 > +						 struct symtab **symtab);
 > +
 > +static void maintenance_cplus_namespace (char *args, int from_tty);
 > +
 >  /* Set up support for dealing with C++ namespace info in the current
 >     symtab.  */
 >  
 > @@ -453,13 +477,268 @@ lookup_symbol_file (const char *name,
 >        const struct block *global_block = block_global_block (block);
 >        
 >        if (global_block != NULL)
 > -	return lookup_symbol_aux_block (name, linkage_name, global_block,
 > -					domain, symtab);
 > -      else
 > -	return NULL;
 > +	sym = lookup_symbol_aux_block (name, linkage_name, global_block,
 > +				       domain, symtab);
 > +    }
 > +  else
 > +    {
 > +      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
 > +    }
 > +
 > +  if (sym != NULL)
 > +    return sym;
 > +
 > +  /* Now call "lookup_possible_namespace_symbol".  Symbols in here
 > +     claim to be associated to namespaces, but this claim might be
 > +     incorrect: the names in question might actually correspond to
 > +     classes instead of namespaces.  But if they correspond to
 > +     classes, then we should have found a match for them above.  So if
 > +     we find them now, they should be genuine.  */
 > +
 > +  /* FIXME: carlton/2003-06-12: This is a hack and should eventually
 > +     be deleted: see comments below.  */
 > +
 > +  if (domain == VAR_DOMAIN)
 > +    {
 > +      sym = lookup_possible_namespace_symbol (name, symtab);
 > +      if (sym != NULL)
 > +	return sym;
 > +    }
 > +
 > +  return NULL;
 > +}
 > +
 > +/* Now come functions for dealing with symbols associated to
 > +   namespaces.  (They're used to store the namespaces themselves, not
 > +   objects that live in the namespaces.)  These symbols come in two
 > +   varieties: if we run into a DW_TAG_namespace DIE, then we know that
 > +   we have a namespace, so dwarf2read.c creates a symbol for it just
 > +   like normal.  But, unfortunately, versions of GCC through at least
 > +   3.3 don't generate those DIE's.  Our solution is to try to guess
 > +   their existence by looking at demangled names.  This might cause us
 > +   to misidentify classes as namespaces, however.  So we put those
 > +   symbols in a special block (one per objfile), and we only search
 > +   that block as a last resort.  */
 > +
 > +/* FIXME: carlton/2003-06-12: Once versions of GCC that generate
 > +   DW_TAG_namespace have been out for a year or two, we should get rid
 > +   of all of this "possible namespace" nonsense.  */
 > +
 > +/* Allocate everything necessary the possible namespace block
 > +   associated to OBJFILE.  */
 > +
 > +static void
 > +initialize_namespace_symtab (struct objfile *objfile)
 > +{
 > +  struct symtab *namespace_symtab;
 > +  struct blockvector *bv;
 > +  struct block *bl;
 > +
 > +  namespace_symtab = allocate_symtab ("<<C++-namespaces>>", objfile);
 > +  namespace_symtab->language = language_cplus;
 > +  namespace_symtab->free_code = free_nothing;
 > +  namespace_symtab->dirname = NULL;
 > +
 > +  bv = obstack_alloc (&objfile->symbol_obstack,
 > +		      sizeof (struct blockvector)
 > +		      + FIRST_LOCAL_BLOCK * sizeof (struct block *));
 > +  BLOCKVECTOR_NBLOCKS (bv) = FIRST_LOCAL_BLOCK + 1;
 > +  BLOCKVECTOR (namespace_symtab) = bv;
 > +  
 > +  /* Allocate empty GLOBAL_BLOCK and STATIC_BLOCK. */
 > +
 > +  bl = allocate_block (&objfile->symbol_obstack);
 > +  BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
 > +					NULL);
 > +  BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
 > +  bl = allocate_block (&objfile->symbol_obstack);
 > +  BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
 > +					NULL);
 > +  BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
 > +
 > +  /* Allocate the possible namespace block; we put it where the first
 > +     local block will live, though I don't think there's any need to
 > +     pretend that it's actually a local block (e.g. by setting
 > +     BLOCK_SUPERBLOCK appropriately).  */
 > +
 > +  bl = allocate_block (&objfile->symbol_obstack);
 > +  BLOCK_DICT (bl) = dict_create_hashed_expandable ();
 > +  BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK) = bl;
 > +
 > +  namespace_symtab->free_func = free_namespace_block;
 > +
 > +  objfile->cp_namespace_symtab = namespace_symtab;
 > +}
 > +
 > +/* Locate the possible namespace block associated to OBJFILE,
 > +   allocating it if necessary.  */
 > +
 > +static struct block *
 > +get_possible_namespace_block (struct objfile *objfile)
 > +{
 > +  if (objfile->cp_namespace_symtab == NULL)
 > +    initialize_namespace_symtab (objfile);
 > +
 > +  return BLOCKVECTOR_BLOCK (BLOCKVECTOR (objfile->cp_namespace_symtab),
 > +			    FIRST_LOCAL_BLOCK);
 > +}
 > +
 > +/* Free the dictionary associated to the possible namespace block.  */
 > +
 > +static void
 > +free_namespace_block (struct symtab *symtab)
 > +{
 > +  struct block *possible_namespace_block;
 > +
 > +  possible_namespace_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
 > +						FIRST_LOCAL_BLOCK);
 > +  gdb_assert (possible_namespace_block != NULL);
 > +  dict_free (BLOCK_DICT (possible_namespace_block));
 > +}
 > +
 > +/* Ensure that there are symbols in the possible namespace block
 > +   associated to OBJFILE for all initial substrings of NAME that look
 > +   like namespaces or classes.  NAME should end in a member variable:
 > +   it shouldn't consist solely of namespaces.  */
 > +
 > +void
 > +cp_check_possible_namespace_symbols (const char *name, struct objfile *objfile)
 > +{
 > +  check_possible_namespace_symbols_loop (name,
 > +					 cp_find_first_component (name),
 > +					 objfile);
 > +}
 > +
 > +/* This is a helper loop for cp_check_possible_namespace_symbols; it
 > +   ensures that there are symbols in the possible namespace block
 > +   associated to OBJFILE for all namespaces that are initial
 > +   substrings of NAME of length at least LEN.  It returns 1 if a
 > +   previous loop had already created the shortest such symbol and 0
 > +   otherwise.
 > +
 > +   This function assumes that if there is already a symbol associated
 > +   to a substring of NAME of a given length, then there are already
 > +   symbols associated to all substrings of NAME whose length is less
 > +   than that length.  So if cp_check_possible_namespace_symbols has
 > +   been called once with argument "A::B::C::member", then that will
 > +   create symbols "A", "A::B", and "A::B::C".  If it is then later
 > +   called with argument "A::B::D::member", then the new call will
 > +   generate a new symbol for "A::B::D", but once it sees that "A::B"
 > +   has already been created, it doesn't bother checking to see if "A"
 > +   has also been created.  */
 > +
 > +static int
 > +check_possible_namespace_symbols_loop (const char *name, int len,
 > +				       struct objfile *objfile)
 > +{
 > +  if (name[len] == ':')
 > +    {
 > +      int done;
 > +      int next_len = len + 2;
 > +
 > +      next_len += cp_find_first_component (name + next_len);
 > +      done = check_possible_namespace_symbols_loop (name, next_len,
 > +						    objfile);
 > +
 > +      if (!done)
 > +	done = check_one_possible_namespace_symbol (name, len, objfile);
 > +
 > +      return done;
 >      }
 >    else
 > +    return 0;
 > +}
 > +
 > +/* Check to see if there's already a possible namespace symbol in
 > +   OBJFILE whose name is the initial substring of NAME of length LEN.
 > +   If not, create one and return 0; otherwise, return 1.  */
 > +
 > +static int
 > +check_one_possible_namespace_symbol (const char *name, int len,
 > +				     struct objfile *objfile)
 > +{
 > +  struct block *block = get_possible_namespace_block (objfile);
 > +  char *name_copy = obsavestring (name, len, &objfile->symbol_obstack);
 > +  struct symbol *sym = lookup_block_symbol (block, name_copy, NULL,
 > +					    VAR_DOMAIN);
 > +
 > +  if (sym == NULL)
 >      {
 > -      return lookup_symbol_global (name, linkage_name, domain, symtab);
 > +      struct type *type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
 > +				     name_copy, objfile);
 > +      TYPE_TAG_NAME (type) = TYPE_NAME (type);
 > +
 > +      sym = obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
 > +      memset (sym, 0, sizeof (struct symbol));
 > +      SYMBOL_LANGUAGE (sym) = language_cplus;
 > +      SYMBOL_SET_NAMES (sym, name_copy, len, objfile);
 > +      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 > +      SYMBOL_TYPE (sym) = type;
 > +      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 > +
 > +      dict_add_symbol (BLOCK_DICT (block), sym);
 > +
 > +      return 0;
 >      }
 > +  else
 > +    {
 > +      obstack_free (&objfile->symbol_obstack, name_copy);
 > +
 > +      return 1;
 > +    }
 > +}
 > +
 > +/* Look for a symbol named NAME in all the possible namespace blocks.
 > +   If one is found, return it; if SYMTAB is non-NULL, set *SYMTAB to
 > +   equal the symtab where it was found.  */
 > +
 > +static struct symbol *
 > +lookup_possible_namespace_symbol (const char *name, struct symtab **symtab)
 > +{
 > +  struct objfile *objfile;
 > +
 > +  ALL_OBJFILES (objfile)
 > +    {
 > +      struct symbol *sym;
 > +
 > +      sym = lookup_block_symbol (get_possible_namespace_block (objfile),
 > +				 name, NULL, VAR_DOMAIN);
 > +
 > +      if (sym != NULL)
 > +	{
 > +	  if (symtab != NULL)
 > +	    *symtab = objfile->cp_namespace_symtab;
 > +
 > +	  return sym;
 > +	}
 > +    }
 > +
 > +  return NULL;
 > +}
 > +
 > +/* Print out all the possible namespace symbols.  */
 > +
 > +static void
 > +maintenance_cplus_namespace (char *args, int from_tty)
 > +{
 > +  struct objfile *objfile;
 > +  printf_unfiltered ("Possible namespaces:\n");
 > +  ALL_OBJFILES (objfile)
 > +    {
 > +      struct dict_iterator iter;
 > +      struct symbol *sym;
 > +
 > +      ALL_BLOCK_SYMBOLS (get_possible_namespace_block (objfile), iter, sym)
 > +	{
 > +	  printf_unfiltered ("%s\n", SYMBOL_PRINT_NAME (sym));
 > +	}
 > +    }
 > +}
 > +
 > +void
 > +_initialize_cp_namespace (void)
 > +{
 > +  add_cmd ("namespace", class_maintenance, maintenance_cplus_namespace,
 > +	   "Print the list of possible C++ namespaces.",
 > +	   &maint_cplus_cmd_list);
 >  }
 > Index: cp-support.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/cp-support.c,v
 > retrieving revision 1.5
 > diff -u -p -r1.5 cp-support.c
 > --- cp-support.c	12 Jun 2003 15:33:45 -0000	1.5
 > +++ cp-support.c	27 Jun 2003 21:38:07 -0000
 > @@ -45,7 +45,7 @@ static void overload_list_add_symbol (st
 >  
 >  /* The list of "maint cplus" commands.  */
 >  
 > -static struct cmd_list_element *maint_cplus_cmd_list = NULL;
 > +struct cmd_list_element *maint_cplus_cmd_list = NULL;
 >  
 >  /* The actual commands.  */
 >  
 > Index: cp-support.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/cp-support.h,v
 > retrieving revision 1.6
 > diff -u -p -r1.6 cp-support.h
 > --- cp-support.h	12 Jun 2003 15:33:45 -0000	1.6
 > +++ cp-support.h	27 Jun 2003 21:38:12 -0000
 > @@ -96,4 +96,11 @@ extern struct symbol *cp_lookup_symbol_n
 >  						  const domain_enum domain,
 >  						  struct symtab **symtab);
 >  
 > +extern void cp_check_possible_namespace_symbols (const char *name,
 > +						 struct objfile *objfile);
 > +
 > +/* The list of "maint cplus" commands.  */
 > +
 > +extern struct cmd_list_element *maint_cplus_cmd_list;
 > +
 >  #endif /* CP_SUPPORT_H */
 > Index: dwarf2read.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/dwarf2read.c,v
 > retrieving revision 1.97
 > diff -u -p -r1.97 dwarf2read.c
 > --- dwarf2read.c	26 Jun 2003 21:20:39 -0000	1.97
 > +++ dwarf2read.c	27 Jun 2003 21:38:33 -0000
 > @@ -678,10 +678,30 @@ static void dwarf2_build_psymtabs_hard (
 >  
 >  static char *scan_partial_symbols (char *, struct objfile *,
 >  				   CORE_ADDR *, CORE_ADDR *,
 > -				   const struct comp_unit_head *);
 > +				   const struct comp_unit_head *,
 > +				   const char *namespace);
 >  
 >  static void add_partial_symbol (struct partial_die_info *, struct objfile *,
 > -				const struct comp_unit_head *);
 > +				const struct comp_unit_head *,
 > +				const char *namespace);
 > +
 > +static char *add_partial_namespace (struct partial_die_info *pdi,
 > +				    char *info_ptr,
 > +				    struct objfile *objfile,
 > +				    CORE_ADDR *lowpc, CORE_ADDR *highpc,
 > +				    const struct comp_unit_head *cu_header,
 > +				    const char *namespace);
 > +
 > +static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
 > +				      char *info_ptr,
 > +				      struct objfile *objfile,
 > +				      const struct comp_unit_head *cu_header,
 > +				      const char *namespace);
 > +
 > +static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
 > +				 char *info_ptr,
 > +				 bfd *abfd,
 > +				 const struct comp_unit_head *cu_header);
 >  
 >  static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 >  
 > @@ -1327,9 +1347,17 @@ dwarf2_build_psymtabs_hard (struct objfi
 >           If not, there's no more debug_info for this comp unit. */
 >        if (comp_unit_die.has_children)
 >  	{
 > +	  lowpc = ((CORE_ADDR) -1);
 > +	  highpc = ((CORE_ADDR) 0);
 > +
 >  	  info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
 > -					   &cu_header);
 > +					   &cu_header, NULL);
 >  
 > +	  /* If we didn't find a lowpc, set it to highpc to avoid
 > +	     complaints from `maint check'.  */
 > +	  if (lowpc == ((CORE_ADDR) -1))
 > +	    lowpc = highpc;
 > +	  
 >  	  /* If the compilation unit didn't have an explicit address range,
 >  	     then use the information extracted from its child dies.  */
 >  	  if (! comp_unit_die.has_pc_info)
 > @@ -1358,45 +1386,40 @@ dwarf2_build_psymtabs_hard (struct objfi
 >    do_cleanups (back_to);
 >  }
 >  
 > -/* Read in all interesting dies to the end of the compilation unit.  */
 > +/* Read in all interesting dies to the end of the compilation unit or
 > +   to the end of the current namespace.  NAMESPACE is NULL if we
 > +   haven't yet encountered any DW_TAG_namespace entries; otherwise,
 > +   it's the name of the current namespace.  In particular, it's the
 > +   empty string if we're currently in the global namespace but have
 > +   previously encountered a DW_TAG_namespace.  */
 >  
 >  static char *
 >  scan_partial_symbols (char *info_ptr, struct objfile *objfile,
 >  		      CORE_ADDR *lowpc, CORE_ADDR *highpc,
 > -		      const struct comp_unit_head *cu_header)
 > +		      const struct comp_unit_head *cu_header,
 > +		      const char *namespace)
 >  {
 >    bfd *abfd = objfile->obfd;
 >    struct partial_die_info pdi;
 >  
 > -  /* This function is called after we've read in the comp_unit_die in
 > -     order to read its children.  We start the nesting level at 1 since
 > -     we have pushed 1 level down in order to read the comp unit's children.
 > -     The comp unit itself is at level 0, so we stop reading when we pop
 > -     back to that level. */
 > -
 > -  int nesting_level = 1;
 > -
 > -  /* We only want to read in symbols corresponding to variables or
 > -     other similar objects that are global or static.  Normally, these
 > -     are all children of the DW_TAG_compile_unit die, so are all at
 > -     level 1.  But C++ namespaces give ries to DW_TAG_namespace dies
 > -     whose children are global objects.  So we keep track of what
 > -     level we currently think of as referring to file scope; this
 > -     should always equal 1 plus the number of namespaces that we are
 > -     currently nested within.  */
 > -  
 > -  int file_scope_level = 1;
 > -
 > -  *lowpc = ((CORE_ADDR) -1);
 > -  *highpc = ((CORE_ADDR) 0);
 > +  /* Now, march along the PDI's, descending into ones which have
 > +     interesting children but skipping the children of the other ones,
 > +     until we reach the end of the compilation unit.  */
 >  
 > -  while (nesting_level)
 > +  while (1)
 >      {
 > +      /* This flag tells whether or not info_ptr has gotten updated
 > +	 inside the loop.  */
 > +      int info_ptr_updated = 0;
 > +
 >        info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
 >  
 > -      /* Anonymous namespaces have no name but are interesting.  */
 > +      /* Anonymous namespaces have no name but have interesting
 > +	 children, so we need to look at them.  Ditto for anonymous
 > +	 enums.  */
 >  
 > -      if (pdi.name != NULL || pdi.tag == DW_TAG_namespace)
 > +      if (pdi.name != NULL || pdi.tag == DW_TAG_namespace
 > +	  || pdi.tag == DW_TAG_enumeration_type)
 >  	{
 >  	  switch (pdi.tag)
 >  	    {
 > @@ -1411,93 +1434,77 @@ scan_partial_symbols (char *info_ptr, st
 >  		    {
 >  		      *highpc = pdi.highpc;
 >  		    }
 > -		  if ((pdi.is_external || nesting_level == file_scope_level)
 > -		      && !pdi.is_declaration)
 > +		  if (!pdi.is_declaration)
 >  		    {
 > -		      add_partial_symbol (&pdi, objfile, cu_header);
 > +		      add_partial_symbol (&pdi, objfile, cu_header, namespace);
 >  		    }
 >  		}
 >  	      break;
 >  	    case DW_TAG_variable:
 >  	    case DW_TAG_typedef:
 > +	    case DW_TAG_union_type:
 >  	    case DW_TAG_class_type:
 >  	    case DW_TAG_structure_type:
 > -	    case DW_TAG_union_type:
 > -	    case DW_TAG_enumeration_type:
 > -	      if ((pdi.is_external || nesting_level == file_scope_level)
 > -		  && !pdi.is_declaration)
 > +	      if (!pdi.is_declaration)
 >  		{
 > -		  add_partial_symbol (&pdi, objfile, cu_header);
 > +		  add_partial_symbol (&pdi, objfile, cu_header, namespace);
 >  		}
 >  	      break;
 > -	    case DW_TAG_enumerator:
 > -	      /* File scope enumerators are added to the partial
 > -	         symbol table.  They're children of the enumeration
 > -	         type die, so they occur at a level one higher than we
 > -	         normally look for.  */
 > -	      if (nesting_level == file_scope_level + 1)
 > -		add_partial_symbol (&pdi, objfile, cu_header);
 > +	    case DW_TAG_enumeration_type:
 > +	      if (!pdi.is_declaration)
 > +		{
 > +		  info_ptr = add_partial_enumeration (&pdi, info_ptr,
 > +						      objfile, cu_header,
 > +						      namespace);
 > +		  info_ptr_updated = 1;
 > +		}
 >  	      break;
 >  	    case DW_TAG_base_type:
 >  	      /* File scope base type definitions are added to the partial
 >  	         symbol table.  */
 > -	      if (nesting_level == file_scope_level)
 > -		add_partial_symbol (&pdi, objfile, cu_header);
 > +	      add_partial_symbol (&pdi, objfile, cu_header, namespace);
 >  	      break;
 >  	    case DW_TAG_namespace:
 > -	      /* FIXME: carlton/2002-10-16: we're not yet doing
 > -		 anything useful with this, but for now make sure that
 > -		 these tags at least don't cause us to miss any
 > -		 important symbols.  */
 > -	      if (pdi.has_children)
 > -		file_scope_level++;
 > +	      /* We've hit a DW_TAG_namespace entry, so we know this
 > +		 file has been compiled using a compiler that
 > +		 generates them; update NAMESPACE to reflect that.  */
 > +	      if (namespace == NULL)
 > +		namespace = "";
 > +	      info_ptr = add_partial_namespace (&pdi, info_ptr, objfile,
 > +						lowpc, highpc, cu_header,
 > +						namespace);
 > +	      info_ptr_updated = 1;
 > +	      break;
 >  	    default:
 >  	      break;
 >  	    }
 >  	}
 >  
 > -      /* If the die has a sibling, skip to the sibling.  Do not skip
 > -         enumeration types, we want to record their enumerators.  Do
 > -         not skip namespaces, we want to record symbols inside
 > -         them.  */
 > -      if (pdi.sibling
 > -	  && pdi.tag != DW_TAG_enumeration_type
 > -	  && pdi.tag != DW_TAG_namespace)
 > -	{
 > -	  info_ptr = pdi.sibling;
 > -	}
 > -      else if (pdi.has_children)
 > -	{
 > -	  /* Die has children, but either the optional DW_AT_sibling
 > -	     attribute is missing or we want to look at them.  */
 > -	  nesting_level++;
 > -	}
 > -
 >        if (pdi.tag == 0)
 > -	{
 > -	  nesting_level--;
 > -	  /* If this is the end of a DW_TAG_namespace entry, then
 > -	     decrease the file_scope_level, too.  */
 > -	  if (nesting_level < file_scope_level)
 > -	    {
 > -	      file_scope_level--;
 > -	      gdb_assert (nesting_level == file_scope_level);
 > -	    }
 > -	}
 > +	break;
 > +
 > +      /* If the die has a sibling, skip to the sibling, unless another
 > +	 function has already updated info_ptr for us.  */
 > +
 > +      /* NOTE: carlton/2003-06-16: This is a bit hackish, but whether
 > +	 or not we want to update this depends on enough stuff (not
 > +	 only pdi.tag but also whether or not pdi.name is NULL) that
 > +	 this seems like the easiest way to handle the issue.  */
 > +
 > +      if (!info_ptr_updated)
 > +	  info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header);
 >      }
 >  
 > -  /* If we didn't find a lowpc, set it to highpc to avoid complaints
 > -     from `maint check'.  */
 > -  if (*lowpc == ((CORE_ADDR) -1))
 > -    *lowpc = *highpc;
 >    return info_ptr;
 >  }


Ok, but, could you check in the algorithm change (the nested_level
stuff) for scan_partial_symbols w/o any namespace changes? So that we
can do a cvs -D if something goes wrong? I have decided that it is
best to have a change per 24hours period to a file, after spending a
couple of days tracking down some other breakage in symfiles, a few
weeks back.  Then the rest of the changes.

 >  
 >  static void
 >  add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
 > -		    const struct comp_unit_head *cu_header)
 > +		    const struct comp_unit_head *cu_header,
 > +		    const char *namespace)
 >  {
 >    CORE_ADDR addr = 0;
 > +  const struct partial_symbol *psym = NULL;
 >  
 >    switch (pdi->tag)
 >      {
 > @@ -1506,19 +1513,21 @@ add_partial_symbol (struct partial_die_i
 >  	{
 >  	  /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
 >  	     mst_text, objfile); */
 > -	  add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > -			       VAR_DOMAIN, LOC_BLOCK,
 > -			       &objfile->global_psymbols,
 > -			    0, pdi->lowpc + baseaddr, cu_language, objfile);
 > +	  psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > +				      VAR_DOMAIN, LOC_BLOCK,
 > +				      &objfile->global_psymbols,
 > +				      0, pdi->lowpc + baseaddr,
 > +				      cu_language, objfile);
 >  	}
 >        else
 >  	{
 >  	  /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
 >  	     mst_file_text, objfile); */
 > -	  add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > -			       VAR_DOMAIN, LOC_BLOCK,
 > -			       &objfile->static_psymbols,
 > -			    0, pdi->lowpc + baseaddr, cu_language, objfile);
 > +	  psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > +				      VAR_DOMAIN, LOC_BLOCK,
 > +				      &objfile->static_psymbols,
 > +				      0, pdi->lowpc + baseaddr,
 > +				      cu_language, objfile);
 >  	}
 >        break;
 >      case DW_TAG_variable:
 > @@ -1540,10 +1549,11 @@ add_partial_symbol (struct partial_die_i
 >  	  if (pdi->locdesc)
 >  	    addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
 >  	  if (pdi->locdesc || pdi->has_type)
 > -	    add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > -				 VAR_DOMAIN, LOC_STATIC,
 > -				 &objfile->global_psymbols,
 > -				 0, addr + baseaddr, cu_language, objfile);
 > +	    psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > +					VAR_DOMAIN, LOC_STATIC,
 > +					&objfile->global_psymbols,
 > +					0, addr + baseaddr,
 > +					cu_language, objfile);
 >  	}
 >        else
 >  	{
 > @@ -1553,10 +1563,11 @@ add_partial_symbol (struct partial_die_i
 >  	  addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
 >  	  /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
 >  	     mst_file_data, objfile); */
 > -	  add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > -			       VAR_DOMAIN, LOC_STATIC,
 > -			       &objfile->static_psymbols,
 > -			       0, addr + baseaddr, cu_language, objfile);
 > +	  psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
 > +				      VAR_DOMAIN, LOC_STATIC,
 > +				      &objfile->static_psymbols,
 > +				      0, addr + baseaddr,
 > +				      cu_language, objfile);
 >  	}
 >        break;
 >      case DW_TAG_typedef:
 > @@ -1597,6 +1608,124 @@ add_partial_symbol (struct partial_die_i
 >      default:
 >        break;
 >      }
 > +
 > +  /* Check to see if we should scan the name for possible namespace
 > +     info.  Only do this if this is C++, if we don't have namespace
 > +     debugging info in the file, if the psym is of an appropriate type
 > +     (otherwise we'll have psym == NULL), and if we actually had a
 > +     mangled name to begin with.  */
 > +
 > +  if (cu_language == language_cplus
 > +      && namespace == NULL
 > +      && psym != NULL
 > +      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
 > +    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
 > +					 objfile);
 > +}
 > +


I don't like this too much. I.e. changing add_psymbol_to_list to
return a value so you can get a hold of the psym. After all,
add_psymbol_to_list doesn't change any of the fields of the psymbol,
and cp_check_possible_namespace_symbols uses 2 fields that you already
have around. Would it be possible to do w/o using psym at all? You
might have to set a local variable to the function.



 > +/* Read a partial die corresponding to a namespace; also, add a symbol
 > +   corresponding to that namespace to the symbol table.  NAMESPACE is
 > +   the name of the enclosing namespace.  */
 > +
 > +static char *
 > +add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
 > +		       struct objfile *objfile,
 > +		       CORE_ADDR *lowpc, CORE_ADDR *highpc,
 > +		       const struct comp_unit_head *cu_header,
 > +		       const char *namespace)
 > +{
 > +  /* Calculate the full name of the namespace that we just entered.  */
 > +
 > +  const char *new_name = pdi->name;
 > +  char *full_name;
 > +
 > +  if (new_name == NULL)
 > +    new_name = "(anonymous namespace)";
 > +  full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1);
 > +  strcpy (full_name, namespace);
 > +  if (*namespace != '\0')
 > +    strcat (full_name, "::");
 > +  strcat (full_name, new_name);
 > +
 > +  /* FIXME: carlton/2003-06-27: Once we build qualified names for more
 > +     symbols than just namespaces, we should replace this by a call to
 > +     add_partial_symbol.  */
 > +
 > +  add_psymbol_to_list (full_name, strlen (full_name),
 > +		       VAR_DOMAIN, LOC_TYPEDEF,
 > +		       &objfile->global_psymbols,
 > +		       0, 0, cu_language, objfile);
 > +
 > +  /* Now scan partial symbols in that namespace.  */
 > +
 > +  if (pdi->has_children)
 > +    info_ptr = scan_partial_symbols (info_ptr, objfile,
 > +				     lowpc, highpc,
 > +				     cu_header, full_name);
 > +
 > +  return info_ptr;
 > +}
 > +
 > +/* Read a partial die corresponding to an enumeration type.  */
 > +
 > +static char *
 > +add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
 > +			 struct objfile *objfile,
 > +			 const struct comp_unit_head *cu_header,
 > +			 const char *namespace)
 > +{
 > +  bfd *abfd = objfile->obfd;
 > +  struct partial_die_info pdi;
 > +
 > +  if (enum_pdi->name != NULL)
 > +    add_partial_symbol (enum_pdi, objfile, cu_header, namespace);
 > +  
 > +  while (1)
 > +    {
 > +      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
 > +      if (pdi.tag == 0)
 > +	break;
 > +      if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL)
 > +	complaint (&symfile_complaints, "malformed enumerator DIE ignored");
 > +      else
 > +	add_partial_symbol (&pdi, objfile, cu_header, namespace);
 > +    }
 > +
 > +  return info_ptr;
 > +}
 > +

Any enumeration related tests that fail before and pass after this change?


 > +/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE
 > +   after ORIG_PDI.  */
 > +
 > +static char *
 > +locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
 > +		    bfd *abfd, const struct comp_unit_head *cu_header)
 > +{
 > +  /* Do we know the sibling already?  */
 > +  
 > +  if (orig_pdi->sibling)
 > +    return orig_pdi->sibling;
 > +
 > +  /* Are there any children to deal with?  */
 > +
 > +  if (!orig_pdi->has_children)
 > +    return info_ptr;
 > +
 > +  /* Okay, we don't know the sibling, but we have children that we
 > +     want to skip.  So read children until we run into one without a
 > +     tag; return whatever follows it.  */
 > +
 > +  while (1)
 > +    {
 > +      struct partial_die_info pdi;
 > +      
 > +      info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
 > +
 > +      if (pdi.tag == 0)
 > +	return info_ptr;
 > +      else
 > +	info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header);
 > +    }
 >  }
 >  
 >  /* Expand this partial symbol table into a full symbol table.  */
 > @@ -3260,6 +3389,23 @@ read_namespace (struct die_info *die, st
 >  			    strlen (previous_namespace),
 >  			    strlen (processing_current_namespace));
 >  
 > +  /* Add a symbol associated to this if we haven't seen the namespace
 > +     before.  */
 > +
 > +  if (dwarf2_extension (die) == NULL)


Could you use this function in the check before this, in
read_namespace (not in this patch, but already in the file)?


 > +    {
 > +      struct type *type;
 > +
 > +      /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
 > +	 this cast will hopefully become unnecessary.  */
 > +      type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
 > +			(char *) processing_current_namespace,
 > +			objfile);
 > +      TYPE_TAG_NAME (type) = TYPE_NAME (type);
 > +
 > +      new_symbol (die, type, objfile, cu_header);
 > +    }
 > +
 >    if (die->has_children)
 >      {
 >        struct die_info *child_die = die->next;
 > @@ -5113,7 +5259,11 @@ new_symbol (struct die_info *die, struct
 >    struct attribute *attr2 = NULL;
 >    CORE_ADDR addr = 0;
 >  
 > -  name = dwarf2_linkage_name (die);
 > +  if (die->tag != DW_TAG_namespace)
 > +    name = dwarf2_linkage_name (die);
 > +  else
 > +    name = TYPE_NAME (type);
 > +
 >    if (name)
 >      {
 >        sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
 > @@ -5291,6 +5441,10 @@ new_symbol (struct die_info *die, struct
 >  	      dwarf2_const_value (attr, sym, objfile, cu_header);
 >  	    }
 >  	  add_symbol_to_list (sym, list_in_scope);
 > +	  break;
 > +	case DW_TAG_namespace:
 > +	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 > +	  add_symbol_to_list (sym, &global_symbols);
 >  	  break;
 >  	default:
 >  	  /* Not a tag we recognize.  Hopefully we aren't processing
 > Index: gdbtypes.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/gdbtypes.c,v
 > retrieving revision 1.74
 > diff -u -p -r1.74 gdbtypes.c
 > --- gdbtypes.c	23 Jun 2003 21:05:40 -0000	1.74
 > +++ gdbtypes.c	27 Jun 2003 21:38:38 -0000
 > @@ -1897,7 +1897,8 @@ init_type (enum type_code code, int leng
 >    if (name && strcmp (name, "char") == 0)
 >      TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN;
 >  
 > -  if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
 > +  if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION
 > +      || code == TYPE_CODE_NAMESPACE)
 >      {
 >        INIT_CPLUS_SPECIFIC (type);
 >      }
 > @@ -3144,6 +3145,9 @@ recursive_dump_type (struct type *type, 
 >        break;
 >      case TYPE_CODE_TEMPLATE_ARG:
 >        printf_filtered ("(TYPE_CODE_TEMPLATE_ARG)");
 > +      break;
 > +    case TYPE_CODE_NAMESPACE:
 > +      printf_filtered ("(TYPE_CODE_NAMESPACE)");
 >        break;
 >      default:
 >        printf_filtered ("(UNKNOWN TYPE CODE)");
 > Index: gdbtypes.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/gdbtypes.h,v
 > retrieving revision 1.48
 > diff -u -p -r1.48 gdbtypes.h
 > --- gdbtypes.h	23 Jun 2003 21:05:40 -0000	1.48
 > +++ gdbtypes.h	27 Jun 2003 21:38:50 -0000
 > @@ -134,8 +134,9 @@ enum type_code
 >  
 >      TYPE_CODE_TYPEDEF,
 >      TYPE_CODE_TEMPLATE,		/* C++ template */
 > -    TYPE_CODE_TEMPLATE_ARG	/* C++ template arg */
 > +    TYPE_CODE_TEMPLATE_ARG,	/* C++ template arg */
 >  
 > +    TYPE_CODE_NAMESPACE,	/* C++ namespace.  */
 >    };
 >  
 >  /* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
 > Index: jv-lang.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/jv-lang.c,v
 > retrieving revision 1.21
 > diff -u -p -r1.21 jv-lang.c
 > --- jv-lang.c	11 Jun 2003 23:29:47 -0000	1.21
 > +++ jv-lang.c	27 Jun 2003 21:38:55 -0000
 > @@ -111,22 +111,13 @@ get_java_class_symtab (void)
 >        BLOCKVECTOR (class_symtab) = bv;
 >  
 >        /* Allocate dummy STATIC_BLOCK. */
 > -      bl = (struct block *)
 > -	obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
 > +      bl = allocate_block (&objfile->symbol_obstack);
 >        BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
 >  					    NULL);
 > -      BLOCK_START (bl) = 0;
 > -      BLOCK_END (bl) = 0;
 > -      BLOCK_FUNCTION (bl) = NULL;
 > -      BLOCK_SUPERBLOCK (bl) = NULL;
 > -      BLOCK_NAMESPACE (bl) = NULL;
 > -      BLOCK_GCC_COMPILED (bl) = 0;
 >        BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
 >  
 > -      /* Allocate GLOBAL_BLOCK.  This has to be relocatable. */
 > -      bl = (struct block *)
 > -	obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
 > -      *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
 > +      /* Allocate GLOBAL_BLOCK.  */
 > +      bl = allocate_block (&objfile->symbol_obstack);
 >        BLOCK_DICT (bl) = dict_create_hashed_expandable ();
 >        BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
 >        class_symtab->free_func = free_class_block;



I think it would make sense, in a next pass, to have all the creation
of blocks go through the new function.




 > Index: objfiles.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/objfiles.c,v
 > retrieving revision 1.33
 > diff -u -p -r1.33 objfiles.c
 > --- objfiles.c	11 Jun 2003 23:29:47 -0000	1.33
 > +++ objfiles.c	27 Jun 2003 21:38:55 -0000
 > @@ -332,10 +332,14 @@ allocate_objfile (bfd *abfd, int flags)
 >    /* Initialize the section indexes for this objfile, so that we can
 >       later detect if they are used w/o being properly assigned to. */
 >  
 > -    objfile->sect_index_text = -1;
 > -    objfile->sect_index_data = -1;
 > -    objfile->sect_index_bss = -1;
 > -    objfile->sect_index_rodata = -1;
 > +  objfile->sect_index_text = -1;
 > +  objfile->sect_index_data = -1;
 > +  objfile->sect_index_bss = -1;
 > +  objfile->sect_index_rodata = -1;
 > +
 > +  /* We don't yet have a C++-specific namespace symtab.  */
 > +
 > +  objfile->cp_namespace_symtab = NULL;
 >  
 >    /* Add this file onto the tail of the linked list of other such files. */
 >  
 > Index: objfiles.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/objfiles.h,v
 > retrieving revision 1.22
 > diff -u -p -r1.22 objfiles.h
 > --- objfiles.h	24 Mar 2003 03:54:48 -0000	1.22
 > +++ objfiles.h	27 Jun 2003 21:39:07 -0000
 > @@ -28,6 +28,7 @@
 >  
 >  struct bcache;
 >  struct htab;
 > +struct symtab;
 >  
 >  /* This structure maintains information on a per-objfile basis about the
 >     "entry point" of the objfile, and the scope within which the entry point
 > @@ -436,6 +437,13 @@ struct objfile
 >      
 >      /* Place to stash various statistics about this objfile */
 >        OBJSTATS;
 > +
 > +    /* A symtab that the C++ code uses to stash special symbols
 > +       associated to namespaces.  */
 > +
 > +    /* FIXME/carlton-2003-06-27: Delete this in a few years once
 > +       "possible namespace symbols" go away.  */
 > +    struct symtab *cp_namespace_symtab;
 >    };
 >  
 >  /* Defines for the objfile flag word. */
 > Index: printcmd.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/printcmd.c,v
 > retrieving revision 1.63
 > diff -u -p -r1.63 printcmd.c
 > --- printcmd.c	9 Jun 2003 15:20:21 -0000	1.63
 > +++ printcmd.c	27 Jun 2003 21:39:09 -0000
 > @@ -315,7 +315,8 @@ print_formatted (struct value *val, regi
 >  	  || TYPE_CODE (type) == TYPE_CODE_ARRAY
 >  	  || TYPE_CODE (type) == TYPE_CODE_STRING
 >  	  || TYPE_CODE (type) == TYPE_CODE_STRUCT
 > -	  || TYPE_CODE (type) == TYPE_CODE_UNION)
 > +	  || TYPE_CODE (type) == TYPE_CODE_UNION
 > +	  || TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
 >  	/* If format is 0, use the 'natural' format for
 >  	 * that type of value.  If the type is non-scalar,
 >  	 * we have to use language rules to print it as
 > Index: symfile.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/symfile.c,v
 > retrieving revision 1.101
 > diff -u -p -r1.101 symfile.c
 > --- symfile.c	27 Jun 2003 13:11:17 -0000	1.101
 > +++ symfile.c	27 Jun 2003 21:39:23 -0000
 > @@ -2631,9 +2631,10 @@ start_psymtab_common (struct objfile *ob
 >  }
 >  
 >  /* Add a symbol with a long value to a psymtab.
 > -   Since one arg is a struct, we pass in a ptr and deref it (sigh).  */
 > +   Since one arg is a struct, we pass in a ptr and deref it (sigh).  
 > +   Return the partial symbol that has been added.  */
 >  
 > -void
 > +const struct partial_symbol *
 >  add_psymbol_to_list (char *name, int namelength, domain_enum domain,
 >  		     enum address_class class,
 >  		     struct psymbol_allocation_list *list, long val,	/* Value as a long */
 > @@ -2676,6 +2677,8 @@ add_psymbol_to_list (char *name, int nam
 >      }
 >    *list->next++ = psym;
 >    OBJSTAT (objfile, n_psyms++);
 > +
 > +  return psym;
 >  }
 >  
 >  /* Add a symbol with a long value to a psymtab. This differs from


See the comments about the dwarf2read.c changes, to see if we can
avoid doing this.


 > Index: symfile.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/symfile.h,v
 > retrieving revision 1.24
 > diff -u -p -r1.24 symfile.h
 > --- symfile.h	11 Jun 2003 22:27:13 -0000	1.24
 > +++ symfile.h	27 Jun 2003 21:39:26 -0000
 > @@ -152,9 +152,12 @@ extern void extend_psymbol_list (struct 
 >  
 >  /* #include "demangle.h" */
 >  
 > -extern void add_psymbol_to_list (char *, int, domain_enum, enum address_class,
 > -				 struct psymbol_allocation_list *, long,
 > -				 CORE_ADDR, enum language, struct objfile *);
 > +extern const
 > +struct partial_symbol *add_psymbol_to_list (char *, int, domain_enum,
 > +					    enum address_class,
 > +					    struct psymbol_allocation_list *,
 > +					    long, CORE_ADDR,
 > +					    enum language, struct objfile *);
 >  
 >  extern void add_psymbol_with_dem_name_to_list (char *, int, char *, int,
 >  					       domain_enum,



Ditto.



 > Index: typeprint.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/typeprint.c,v
 > retrieving revision 1.18
 > diff -u -p -r1.18 typeprint.c
 > --- typeprint.c	8 Jun 2003 18:27:14 -0000	1.18
 > +++ typeprint.c	27 Jun 2003 21:39:28 -0000
 > @@ -307,6 +307,7 @@ print_type_scalar (struct type *type, LO
 >      case TYPE_CODE_MEMBER:
 >      case TYPE_CODE_METHOD:
 >      case TYPE_CODE_REF:
 > +    case TYPE_CODE_NAMESPACE:
 >        error ("internal error: unhandled type in print_type_scalar");
 >        break;
 >  
 > Index: testsuite/gdb.c++/maint.exp
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/maint.exp,v
 > retrieving revision 1.2
 > diff -u -p -r1.2 maint.exp
 > --- testsuite/gdb.c++/maint.exp	23 Apr 2003 23:45:24 -0000	1.2
 > +++ testsuite/gdb.c++/maint.exp	27 Jun 2003 21:39:29 -0000
 > @@ -29,13 +29,19 @@ if $tracelevel then {
 >  # Test the help messages.
 >  
 >  proc test_help {} {
 > -    gdb_test "help maintenance cplus" "C\\+\\+ maintenance commands.\r\n\r\nList of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- Print the first class/namespace component of NAME\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
 > +    set first_component_help "Print the first class/namespace component of NAME"
 > +    set namespace_help "Print the list of possible C\\+\\+ namespaces"
 >  
 > -    gdb_test "help maint cp" "C\\+\\+ maintenance commands.\r\n\r\nList of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- Print the first class/namespace component of NAME\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
 > +    set multiple_help_body "List of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- ${first_component_help}\r\nmaintenance cplus namespace -- ${namespace_help}\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
 >  
 > -    gdb_test "maint cp" "\"maintenance cplus\" must be followed by the name of a command.\r\nList of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- Print the first class/namespace component of NAME\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
 > +    set help_maint_cp "C\\+\\+ maintenance commands.\r\n\r\n${multiple_help_body}"
 >  
 > -    gdb_test "help maint cp first_component" "Print the first class/namespace component of NAME."
 > +    gdb_test "help maintenance cplus" "${help_maint_cp}"
 > +    gdb_test "help maint cp" "${help_maint_cp}"
 > +    gdb_test "maint cp" "\"maintenance cplus\" must be followed by the name of a command.\r\n${multiple_help_body}"
 > +
 > +    gdb_test "help maint cp first_component" "${first_component_help}."
 > +    gdb_test "help maint cp namespace" "${namespace_help}."
 >  }
 >  
 >  # This is used when NAME should contain only a single component.  Be
 > @@ -79,6 +85,12 @@ proc test_first_component {} {
 >      gdb_test "maint cp first_component foo::bar::baz" "foo"
 >      gdb_test "maint cp first_component C<A>::bar" "C<A>"
 >      gdb_test "maint cp first_component C<std::basic_streambuf<wchar_t,std::char_traits<wchar_t> > >::bar" "C<std::basic_streambuf<wchar_t,std::char_traits<wchar_t> > >"
 > +}
 > +
 > +proc test_namespace {} {
 > +    # There's not a lot we can do to test this.
 > +
 > +    gdb_test "maint cp namespace" "Possible namespaces:"
 >  }
 >  
 >  gdb_exit
 > Index: testsuite/gdb.c++/namespace.exp
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/namespace.exp,v
 > retrieving revision 1.13
 > diff -u -p -r1.13 namespace.exp
 > --- testsuite/gdb.c++/namespace.exp	20 May 2003 03:56:29 -0000	1.13
 > +++ testsuite/gdb.c++/namespace.exp	27 Jun 2003 21:39:29 -0000
 > @@ -208,6 +208,8 @@ gdb_test "print cd" "\\$\[0-9\].* = 3"
 >  gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
 >  gdb_test "print shadow" "\\$\[0-9\].* = 13"
 >  gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
 > +gdb_test "ptype C" "type = namespace C::C"
 > +gdb_test "ptype E" "type = namespace C::D::E"
 >  
 >  # Some anonymous namespace tests.
 >  


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