From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3079 invoked by alias); 9 Sep 2003 19:42:57 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 3064 invoked from network); 9 Sep 2003 19:42:53 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 9 Sep 2003 19:42:53 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h89Jgql28146 for ; Tue, 9 Sep 2003 15:42:52 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h89Jgpe02913 for ; Tue, 9 Sep 2003 15:42:51 -0400 Received: from localhost.redhat.com (porkchop.devel.redhat.com [172.16.58.2]) by pobox.corp.redhat.com (8.12.8/8.12.8) with ESMTP id h89Jgoba000638 for ; Tue, 9 Sep 2003 15:42:50 -0400 Received: by localhost.redhat.com (Postfix, from userid 469) id 402942CB35; Tue, 9 Sep 2003 15:51:38 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16222.12105.616302.481564@localhost.redhat.com> Date: Tue, 09 Sep 2003 19:42:00 -0000 To: David Carlton Cc: gdb-patches@sources.redhat.com Subject: Re: [rfa] generate symbols associated to namespaces In-Reply-To: References: <20030622173547.GA22603@nevyn.them.org> <20030624185019.GA24662@nevyn.them.org> X-SW-Source: 2003-09/txt/msg00171.txt.bz2 David Carlton writes: > On Fri, 27 Jun 2003 09:04:13 -0700, David Carlton 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 > > * 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 > > * 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 ("<>", 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::bar" "C" > gdb_test "maint cp first_component C > >::bar" "C > >" > +} > + > +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. >