diff options
author | David Carlton <carlton@bactrian.org> | 2002-10-15 00:20:32 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2002-10-15 00:20:32 +0000 |
commit | 6a11b22bc00422a587a439ad3c6a085dc965b0d2 (patch) | |
tree | a44d2d6abd3c6201b7a2a8fa6c845a41f8c6753b /gdb | |
parent | 6ef1ea4da8422faa48256d3ee48aea8331eefe85 (diff) | |
download | gdb-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/ChangeLog | 25 | ||||
-rw-r--r-- | gdb/buildsym.c | 93 | ||||
-rw-r--r-- | gdb/buildsym.h | 3 | ||||
-rw-r--r-- | gdb/cp-support.c | 18 | ||||
-rw-r--r-- | gdb/cp-support.h | 30 | ||||
-rw-r--r-- | gdb/symtab.c | 56 |
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, |