summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2002-11-22 17:15:56 +0000
committerDavid Carlton <carlton@bactrian.org>2002-11-22 17:15:56 +0000
commiteaeffedefaf5d7728c092506e48092ec09234d6b (patch)
tree662f57f6ef228692174f340481f3d4ef37107a39
parentbf6d52e491072f2fc5532a8e592f491359b2df67 (diff)
downloadgdb-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.cplus50
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/buildsym.c87
-rw-r--r--gdb/buildsym.h7
-rw-r--r--gdb/cp-support.c6
-rw-r--r--gdb/cp-support.h10
-rw-r--r--gdb/dwarf2read.c30
-rw-r--r--gdb/jv-lang.c2
-rw-r--r--gdb/symtab.c410
-rw-r--r--gdb/symtab.h26
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 *);