diff options
author | David Carlton <carlton@bactrian.org> | 2002-11-22 17:15:56 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2002-11-22 17:15:56 +0000 |
commit | eaeffedefaf5d7728c092506e48092ec09234d6b (patch) | |
tree | 662f57f6ef228692174f340481f3d4ef37107a39 | |
parent | bf6d52e491072f2fc5532a8e592f491359b2df67 (diff) | |
download | gdb-eaeffedefaf5d7728c092506e48092ec09234d6b.tar.gz |
2002-11-22 David Carlton <carlton@math.stanford.edu>
* symtab.h: Add opaque declarations for struct namespace_info and
struct obstack.
(struct block): The language_specific stuff is now a struct
namespace_info rather than a struct using_direct_node.
(BLOCK_NAMESPACE): New macro.
Delete macro BLOCK_USING.
Add declarations for block_using, block_all_usings,
block_set_using, block_scope, block_set_scope.
* symtab.c: #include "gdb_assert.h"
(lookup_symbol_aux): Move minsym stuff inside
lookup_symbol_aux_nonlocal, and always do global search via
lookup_symbol_aux_using.
(lookup_symbol_aux_nonlocal): Do minsym search.
(lookup_symbol_aux_using): Calculate usings via block_all_usings;
handle namespace scope.
(lookup_symbol_aux_using_loop): New function, not to be confused
with the previous function of the same name. (Sorry about that.)
(lookup_symbol_namespace): Renamed from
lookup_symbol_aux_using_loop.
(lookup_symbol_aux_minsyms): Add block_index argument, delete
is_a_field_of_this argument, and only check either global or
static symbols rather than both of them.
(block_using): New function.
(block_all_usings): New function.
(block_set_using): New function.
(block_scope): New function.
(block_set_scope): New function.
(block_initialize_namespace): New function.
* jv-lang.c (get_java_class_symtab): BLOCK_NAMESPACE instead of
BLOCK_USING.
* dwarf2read.c: Delete variable current_namespace, and replace its
uses by processing_current_namespace (from buildsym.h).
(scan_partial_symbols): Allow empty pdi.name if we're
reading a namespace.
* cp-support.h (struct namespace_info): New struct.
* cp-support.c: Add comment.
* buildsym.h: New variable processing_current_namespace.
* buildsym.c (add_symbol_to_list): Do fast search for
"(anonymous namespace)".
(scan_for_anonymous_namespaces): Delete FIXME. Convert for loop
into a clearer while loop.
(finish_block): Replace BLOCK_USING by BLOCK_NAMESPACE.
(finish_block): Set block_scope of function blocks rather than
generating using directives that would have a similar effect.
(end_symtab): Set using via block_set_using rather than
BLOCK_USING.
* Makefile.in (symtab.o): Depend on gdb_assert_h.
-rw-r--r-- | gdb/ChangeLog.cplus | 50 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/buildsym.c | 87 | ||||
-rw-r--r-- | gdb/buildsym.h | 7 | ||||
-rw-r--r-- | gdb/cp-support.c | 6 | ||||
-rw-r--r-- | gdb/cp-support.h | 10 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 30 | ||||
-rw-r--r-- | gdb/jv-lang.c | 2 | ||||
-rw-r--r-- | gdb/symtab.c | 410 | ||||
-rw-r--r-- | gdb/symtab.h | 26 |
10 files changed, 452 insertions, 178 deletions
diff --git a/gdb/ChangeLog.cplus b/gdb/ChangeLog.cplus index f3d29f7a192..4784c6aa6a3 100644 --- a/gdb/ChangeLog.cplus +++ b/gdb/ChangeLog.cplus @@ -1,3 +1,53 @@ +2002-11-22 David Carlton <carlton@math.stanford.edu> + + * symtab.h: Add opaque declarations for struct namespace_info and + struct obstack. + (struct block): The language_specific stuff is now a struct + namespace_info rather than a struct using_direct_node. + (BLOCK_NAMESPACE): New macro. + Delete macro BLOCK_USING. + Add declarations for block_using, block_all_usings, + block_set_using, block_scope, block_set_scope. + * symtab.c: #include "gdb_assert.h" + (lookup_symbol_aux): Move minsym stuff inside + lookup_symbol_aux_nonlocal, and always do global search via + lookup_symbol_aux_using. + (lookup_symbol_aux_nonlocal): Do minsym search. + (lookup_symbol_aux_using): Calculate usings via block_all_usings; + handle namespace scope. + (lookup_symbol_aux_using_loop): New function, not to be confused + with the previous function of the same name. (Sorry about that.) + (lookup_symbol_namespace): Renamed from + lookup_symbol_aux_using_loop. + (lookup_symbol_aux_minsyms): Add block_index argument, delete + is_a_field_of_this argument, and only check either global or + static symbols rather than both of them. + (block_using): New function. + (block_all_usings): New function. + (block_set_using): New function. + (block_scope): New function. + (block_set_scope): New function. + (block_initialize_namespace): New function. + * jv-lang.c (get_java_class_symtab): BLOCK_NAMESPACE instead of + BLOCK_USING. + * dwarf2read.c: Delete variable current_namespace, and replace its + uses by processing_current_namespace (from buildsym.h). + (scan_partial_symbols): Allow empty pdi.name if we're + reading a namespace. + * cp-support.h (struct namespace_info): New struct. + * cp-support.c: Add comment. + * buildsym.h: New variable processing_current_namespace. + * buildsym.c (add_symbol_to_list): Do fast search for + "(anonymous namespace)". + (scan_for_anonymous_namespaces): Delete FIXME. Convert for loop + into a clearer while loop. + (finish_block): Replace BLOCK_USING by BLOCK_NAMESPACE. + (finish_block): Set block_scope of function blocks rather than + generating using directives that would have a similar effect. + (end_symtab): Set using via block_set_using rather than + BLOCK_USING. + * Makefile.in (symtab.o): Depend on gdb_assert_h. + 2002-11-01 Daniel Jacobowitz <drow@mvista.com> * c-typeprint.c (c_type_print_args): Remove. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index a6172f53673..3e2ffd341f0 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2206,7 +2206,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_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) diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 7bbc0e6f8a8..6e082186aca 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -160,7 +160,9 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead) 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); } @@ -175,27 +177,26 @@ static void scan_for_anonymous_namespaces (struct symbol *symbol) { const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol); - const char *beginning, *end; + const char *beginning = name; + const char *end = cp_find_first_component (beginning); - /* 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 "::"-. */ - beginning = end + 2, end = cp_find_first_component (beginning)) + while (*end == ':') { if ((end - beginning) == ANONYMOUS_NAMESPACE_LEN && strncmp (beginning, "(anonymous namespace)", ANONYMOUS_NAMESPACE_LEN) == 0) - /* We've found a component of the name that's an anonymous - namespace. So add symbols in it to the namespace given by - the previous component if there is one, or to the global - namespace if there isn't. */ - add_using_directive (name, - beginning == name ? 0 : beginning - name - 2, - end - name); + { + /* We've found a component of the name that's an anonymous + namespace. So add symbols in it to the namespace given + by the previous component if there is one, or to the + global namespace if there isn't. */ + add_using_directive (name, + beginning == name ? 0 : beginning - name - 2, + end - name); + } + /* The "+ 2" is for the "::". */ + beginning = end + 2; + end = cp_find_first_component (beginning); } } @@ -384,7 +385,7 @@ finish_block (struct symbol *symbol, struct pending **listhead, 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 +486,38 @@ finish_block (struct symbol *symbol, struct pending **listhead, 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. */ + + current = name; + next = cp_find_first_component (current); + while (*next == ':') + { + current = next; + /* The '+ 2' is to skip the '::'. */ + next = cp_find_first_component (current + 2); + } + 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 +1081,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) 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; } } diff --git a/gdb/buildsym.h b/gdb/buildsym.h index 3b8c16fa19f..6229e060e00 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -99,6 +99,13 @@ EXTERN unsigned char processing_hp_compilation; 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; diff --git a/gdb/cp-support.c b/gdb/cp-support.c index a13967f9f82..a5a6db088ee 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -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? */ diff --git a/gdb/cp-support.h b/gdb/cp-support.h index bb89c6fe26f..70963040f0a 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -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, diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0dac67fc3df..f353d404230 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -388,13 +388,6 @@ static struct partial_die_info zeroed_partial_die; 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 @@ -1370,7 +1363,9 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, { info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); - if (pdi.name) + /* Anonymous namespaces have no name but are interesting. */ + + if (pdi.name != NULL || pdi.tag == DW_TAG_namespace) { switch (pdi.tag) { @@ -1632,7 +1627,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) 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 +2993,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 +3016,19 @@ read_namespace (struct die_info *die, struct objfile *objfile, /* 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 +3042,7 @@ read_namespace (struct die_info *die, struct objfile *objfile, } } - current_namespace = previous_namespace; + processing_current_namespace = previous_namespace; } /* Extract all information from a DW_TAG_pointer_type DIE and add to diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c index 03bf565da8a..40044a23c93 100644 --- a/gdb/jv-lang.c +++ b/gdb/jv-lang.c @@ -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; diff --git a/gdb/symtab.c b/gdb/symtab.c index c1d7d3cfc72..5ca6b437e89 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -50,6 +50,7 @@ #include <ctype.h> #include "cp-abi.h" #include "cp-support.h" +#include "gdb_assert.h" /* Prototypes for local functions */ @@ -119,22 +120,30 @@ struct symbol *lookup_symbol_aux_using (const char *name, 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 *, namespace_enum, int); 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, const char *mangled_name, } } - /* 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. */ + /* 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. - 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. */ + 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. */ - /* 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; - } + /* 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. */ -#ifndef HPUXHPPA - - /* 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 *name, const char *mangled_name, 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_index, 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_index, const char *name, /* 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_using (const char *name, 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 *prefix, 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 *prefix, 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 *name, 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 *name, { /* 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 *name, 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 *name, } 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 block *b) 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. */ diff --git a/gdb/symtab.h b/gdb/symtab.h index 063a93042c1..df51e2af641 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -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 @@ -1144,6 +1145,19 @@ 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); extern struct type *lookup_transparent_type (const char *); |