summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2002-10-15 00:20:32 +0000
committerDavid Carlton <carlton@bactrian.org>2002-10-15 00:20:32 +0000
commit6a11b22bc00422a587a439ad3c6a085dc965b0d2 (patch)
treea44d2d6abd3c6201b7a2a8fa6c845a41f8c6753b /gdb
parent6ef1ea4da8422faa48256d3ee48aea8331eefe85 (diff)
downloadgdb-6a11b22bc00422a587a439ad3c6a085dc965b0d2.tar.gz
2002-10-14 David Carlton <carlton@math.stanford.edu>
* buildsym.c (add_using_directive): Rewrite to match new version of struct using_direct. (finish_block): Ditto. * symtab.c (lookup_symbol_aux_using_loop): Add 'prefix_len' argument; rewrite to match new version of struct using_direct. * cp-support.h: Update declaration for cp_add_using. * cp-support.c (cp_add_using): Rewrite to match new version of struct using_direct. * cp-support.h (struct using_direct): Rewrite struct. * buildsym.h: Declaration for add_using_directive. * buildsym.c: New variable 'using_list'. (start_symtab): Initialize using_list. (end_symtab): Initialize BLOCK_USING of STATIC_BLOCK. (scan_for_anonymous_namespaces): New function. (add_symbol_to_list): In C++ case, look for anonymous namespaces. (add_using_directive): New function.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog25
-rw-r--r--gdb/buildsym.c93
-rw-r--r--gdb/buildsym.h3
-rw-r--r--gdb/cp-support.c18
-rw-r--r--gdb/cp-support.h30
-rw-r--r--gdb/symtab.c56
6 files changed, 176 insertions, 49 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index eb9a49782dc..c6ddf0a1bf2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,28 @@
+2002-10-14 David Carlton <carlton@math.stanford.edu>
+
+ * buildsym.c (add_using_directive): Rewrite to match new version
+ of struct using_direct.
+ (finish_block): Ditto.
+
+ * symtab.c (lookup_symbol_aux_using_loop): Add 'prefix_len'
+ argument; rewrite to match new version of struct using_direct.
+
+ * cp-support.h: Update declaration for cp_add_using.
+
+ * cp-support.c (cp_add_using): Rewrite to match new version of
+ struct using_direct.
+
+ * cp-support.h (struct using_direct): Rewrite struct.
+
+ * buildsym.h: Declaration for add_using_directive.
+
+ * buildsym.c: New variable 'using_list'.
+ (start_symtab): Initialize using_list.
+ (end_symtab): Initialize BLOCK_USING of STATIC_BLOCK.
+ (scan_for_anonymous_namespaces): New function.
+ (add_symbol_to_list): In C++ case, look for anonymous namespaces.
+ (add_using_directive): New function.
+
2002-10-11 David Carlton <carlton@math.stanford.edu>
* jv-lang.c (get_java_class_symtab): Initialize BLOCK_USING (bl)
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 612f6994a56..a2322e24eeb 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -63,8 +63,15 @@ static struct pending *free_pendings;
otherwise empty symtab from being tossed. */
static int have_line_numbers;
+
+/* List of using directives that are active in the current file. */
+
+static struct using_direct_node *using_list;
+
static int compare_line_numbers (const void *ln1p, const void *ln2p);
+
+static void scan_for_anonymous_namespaces (struct symbol *symbol);
/* Initial sizes of data structures. These are realloc'd larger if
@@ -108,7 +115,9 @@ add_free_pendings (struct pending *list)
}
}
-/* Add a symbol to one of the lists of symbols. */
+/* Add a symbol to one of the lists of symbols. While we're at it,
+ check to see if it references an anonymous namespace; if so, add an
+ appropriate using directive. */
void
add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
@@ -139,6 +148,48 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
}
(*listhead)->symbol[(*listhead)->nsyms++] = symbol;
+
+ /* Check to see if we might need to look for a mention of anonymous
+ namespaces. */
+ /* TODOTODO */
+/* if (SYMBOL_LANGUAGE (symbol) == language_cplus */
+/* && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL) */
+/* scan_for_anonymous_namespaces (symbol) */
+}
+
+/* Check to see if a symbol is contained within an anonymous
+ namespace; if so, add an appropriate using directive. */
+
+/* Optimize away strlen ("(anonymous namespace)"). */
+
+#define ANONYMOUS_NAMESPACE_LEN 21
+
+static void
+scan_for_anonymous_namespaces (struct symbol *symbol)
+{
+ 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 ':'. */
+ beginning = end + 2, end = cp_find_first_component (beginning))
+ {
+ 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);
+ }
}
/* Find a symbol named NAME on a LIST. NAME need not be
@@ -166,6 +217,32 @@ find_symbol_in_list (struct pending *list, char *name, int length)
return (NULL);
}
+/* This adds a using directive to using_list. NAME is the start of a
+ string that should contain the namespaces we want to add as initial
+ substrings, OUTER_INDEX is the end of the outer namespace, and
+ INNER_INDEX is the end of the inner namespace. If the using
+ directive in question has already been added, don't add it
+ twice. */
+
+void
+add_using_directive (const char *name, unsigned int outer_index,
+ unsigned int inner_index)
+{
+ struct using_direct_node *current;
+
+ gdb_assert (outer_index < inner_index);
+
+ /* Has it already been added? */
+
+ for (current = using_list; current; current = current->next)
+ if (strncmp (current->current->name, name, outer_index) == 0
+ && strncmp (current->current->name, name, inner_index) == 0)
+ return;
+
+ /* TODOTODO */
+}
+
+
/* At end of reading syms, or in case of quit, really free as many
`struct pending's as we can easily find. */
@@ -366,11 +443,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
/* The '+ 2' is to skip the '::'. */
next = cp_find_first_component (next + 2))
{
- const char *namespace_name
- = obsavestring (name, next - name,
- &objfile->symbol_obstack);
BLOCK_USING (block)
- = cp_add_using ("", namespace_name, BLOCK_USING (block),
+ = cp_add_using (name, 0, next - name, BLOCK_USING (block),
&objfile->symbol_obstack);
}
@@ -803,6 +877,7 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
global_symbols = NULL;
within_function = 0;
have_line_numbers = 0;
+ using_list = NULL;
/* Context stack is initially empty. Allocate first one with room
for 10 levels; reuse it forever afterward. */
@@ -936,6 +1011,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
objfile);
blockvector = make_blockvector (objfile);
+ /* TODOTODO */
+/* BLOCK_USING (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK)) */
+/* = cp_copy_usings_obstack (using_list, &objfile->symbol_obstack); */
+/* cp_deep_free_usings (using_list); */
}
#ifndef PROCESS_LINENUMBER_HOOK
@@ -1066,6 +1145,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
return symtab;
}
+/* Search the block for global symbols indicating the presence of
+ anonymous namespaces; add using declarations for them, if
+ found. */
+
/* Push a context block. Args are an identifying nesting level
(checkable when you pop it), and the starting PC address of this
context. */
diff --git a/gdb/buildsym.h b/gdb/buildsym.h
index 8a252cb2b4c..1e678d01016 100644
--- a/gdb/buildsym.h
+++ b/gdb/buildsym.h
@@ -240,6 +240,9 @@ extern void add_symbol_to_list (struct symbol *symbol,
extern struct symbol *find_symbol_in_list (struct pending *list,
char *name, int length);
+extern void add_using_directive (const char *name, unsigned int outer_index,
+ unsigned int inner_index);
+
extern void finish_block (struct symbol *symbol,
struct pending **listhead,
struct pending_block *old_blocks,
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 09c5d542475..d5ca1a1364c 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -171,12 +171,14 @@ method_name_from_physname (const char *physname)
}
/* This allocates a new using_direct structure initialized to contain
- OUTER and INNER, and puts it at the beginning of the linked list
- given by NEXT. It returns the resulting struct using_direct_node.
- All memory is allocated using OBSTACK. */
+ NAME, OUTER_LENGTH, and INNER_LENGTH, and puts it at the beginning
+ of the linked list given by NEXT. It returns the resulting struct
+ using_direct_node. All memory is allocated using OBSTACK. */
struct using_direct_node *
-cp_add_using (const char *outer, const char *inner,
+cp_add_using (const char *name,
+ unsigned short outer_length,
+ unsigned short inner_length,
struct using_direct_node *next,
struct obstack *obstack)
{
@@ -185,8 +187,11 @@ cp_add_using (const char *outer, const char *inner,
struct using_direct_node *retval
= obstack_alloc (obstack, sizeof (struct using_direct_node));
- current->outer = outer;
- current->inner = inner;
+ gdb_assert (outer_length < inner_length);
+
+ current->name = name;
+ current->outer_length = outer_length;
+ current->inner_length = inner_length;
retval->current = current;
retval->next = next;
@@ -195,6 +200,7 @@ cp_add_using (const char *outer, const char *inner,
/* This copies the using_direct_nodes in TOCOPY, using xmalloc, and
sticks them onto a list ending in TAIL. */
+
struct using_direct_node *
cp_copy_usings (struct using_direct_node *tocopy,
struct using_direct_node *tail)
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 500521c2d8b..31eab6e3ba6 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -31,15 +31,19 @@ extern char *method_name_from_physname (const char *physname);
extern const char *cp_find_first_component (const char *name);
/* This is a struct to store data from "using directives" and similar
- language constructs. It contains two strings, OUTER and INNER;
- both should be fully-qualified namespace names, OUTER should be a
- strict initial substring of INNER, and it says that names in the
- namespace INNER should be imported into namespace OUTER. For
- example, if it is used to represent the directive "using namespace
- std;" then INNER should be "std" and new should be "". For a more
+ language constructs. NAME is a pointer to a string; its initial
+ substrings of length OUTER_LENGTH and INNER_LENGTH should both be
+ fully-qualified namespace names. (And OUTER_LENGTH should be
+ strictly less than INNER_LENGTH). The meaning is that names in the
+ inner namespace should be imported into outer.
+
+ For example, if it is used to represent the directive "using
+ namespace std;" then NAME should start with "std", INNER_LENGTH
+ should be 0, and OUTER_LENGTH should be "3". For a more
complicated example, if there is an anonymous namespace with a
- named namespace A, then INNER should be "A::(anonymous namespace)"
- and new should be "A". */
+ named namespace A, then NAME should start with "A::(anonymous
+ namespace)", INNER_LENGTH should be 1, and OUTER_LENGTH should be
+ strlen ("A::(anonymous namespace)"). */
/* FIXME: carlton/2002-10-07: That anonymous namespace example isn't
that great, since it really depends not only on what the
@@ -50,8 +54,9 @@ extern const char *cp_find_first_component (const char *name);
struct using_direct
{
- const char *outer;
- const char *inner;
+ const char *name;
+ unsigned short outer_length;
+ unsigned short inner_length;
};
/* This is a struct for a linked list of using_direct's. */
@@ -62,8 +67,9 @@ struct using_direct_node
struct using_direct_node *next;
};
-extern struct using_direct_node *cp_add_using (const char *outer,
- const char *inner,
+extern struct using_direct_node *cp_add_using (const char *name,
+ unsigned short outer_length,
+ unsigned short inner_length,
struct using_direct_node *next,
struct obstack *obstack);
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 341f95f26c5..5db5b6a559b 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -126,6 +126,7 @@ struct symbol *lookup_symbol_aux_using (const char *name,
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,
@@ -1066,19 +1067,15 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
block = BLOCK_SUPERBLOCK (block);
}
- sym = lookup_symbol_aux_using_loop ("", name, using, mangled_name,
+ sym = lookup_symbol_aux_using_loop ("", 0, name, using, mangled_name,
namespace, symtab);
cp_free_usings (using);
return sym;
}
-/* This tries to look up a symbol whose name is the concatenation of
- PREFIX, "::", and REST, where "::" is ommitted if PREFIX is the
- empty string, applying the various using directives given in USING.
- When applying the using directives, however, it assumes that the
- part of the name given by PREFIX is immutable, so it only adds
- symbols to namespaces whose names contain PREFIX.
+/* 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
global namespace, adding A::inner to namespace A, and adding B to
@@ -1090,11 +1087,7 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
A::foo, A::inner::foo, and B::foo. (Though if the original caller
to lookup_symbol had specified A::foo, we would want to look up
stuff in A::A::foo, A::inner::A::foo, A::inner::foo, and
- B::A::foo).
-
- The reason why this treates the case of PREFIX = "" specially is to
- avoid having to create temporary strings with "::" stuck on the end
- of them. */
+ B::A::foo). */
/* FIXME: carlton/2002-10-11: There are still some places where this
will return false positives. For example, if you have namespaces
@@ -1106,7 +1099,9 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
for other reasons, but it will take a little while.) */
static struct symbol *
-lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
+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,
@@ -1114,22 +1109,28 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
{
struct using_direct_node *current;
struct symbol *sym;
- int prefix_len = strlen (prefix);
for (current = using; current; current = current->next)
{
/* First, see if the prefix matches the start of this using
directive. */
- if (strncmp (prefix, current->current->outer, prefix_len) == 0)
+ if (prefix_len >= current->current->outer_length
+ && strncmp (prefix, current->current->name, prefix_len) == 0)
{
/* Great, it matches: now does the rest of the using
directive match the rest of the name? */
- const char *rest_of_outer = current->current->outer + prefix_len;
- /* Should we skip some colons? */
+ const char *rest_of_outer = current->current->name + prefix_len;
+ int rest_of_outer_len
+ = current->current->outer_length - prefix_len;
+ /* Should we skip some colons? (Should always be true
+ unless PREFIX_LEN is zero (and hence we're in the global
+ namespace.) */
if (*rest_of_outer == ':')
- rest_of_outer += 2;
- int rest_of_outer_len = strlen (rest_of_outer);
+ {
+ rest_of_outer += 2;
+ rest_of_outer_len -= 2;
+ }
if (strncmp (rest_of_outer, rest, rest_of_outer_len) == 0)
{
/* Everything matches! Yippee! So apply the using
@@ -1138,12 +1139,14 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
if (*new_rest == ':')
new_rest += 2;
- sym = lookup_symbol_aux_using_loop (current->current->inner,
- new_rest,
- using,
- mangled_name,
- namespace,
- symtab);
+ sym = lookup_symbol_aux_using_loop
+ (current->current->name,
+ current->current->inner_length,
+ new_rest,
+ using,
+ mangled_name,
+ namespace,
+ symtab);
if (sym != NULL)
return sym;
}
@@ -1153,6 +1156,7 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
/* We didn't find anything by applying any of the using directives
that are still applicable; so let's see if we've got a match
using the current name. */
+
if (prefix_len == 0)
{
return lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, rest, mangled_name,
@@ -1162,7 +1166,7 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
{
char *concatenated_name
= xmalloc (prefix_len + 2 + strlen (rest) + 1);
- strcpy (concatenated_name, prefix);
+ strncpy (concatenated_name, prefix, prefix_len);
strcpy (concatenated_name + prefix_len, "::");
strcpy (concatenated_name + prefix_len + 2, rest);
sym = lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, concatenated_name,