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