From f3c2ac2142055f5a9c8fa3c76b25f866e9c30d25 Mon Sep 17 00:00:00 2001 From: David Carlton Date: Wed, 12 Feb 2003 23:37:10 +0000 Subject: 2003-02-12 David Carlton * linespec.c (examine_compound_token): Call decode_namespace. (decode_namespace): New function. * cp-support.c (cp_find_first_component): Return the offset, not a pointer. (check_possible_namespace_symbols_loop): Update call to cp_find_first_component. (cp_check_possible_namespace_symbols): Ditto. (cp_func_name): Ditto. * buildsym.c (scan_for_anonymous_namespaces): Ditto. (finish_block): Ditto. * linespec.c (examine_compound_token): Ditto. * symtab.c (lookup_symbol_aux_using_loop): Ditto. * valops.c (find_oload_champ_namespace_loop): Ditto. * cp-support.h: Declare cp_find_first_component to return an int. * Makefile.in (linespec.o): cp_support_h. * linespec.c (symtab_from_filename): Rename from handle_filename. (decode_line_1): Call symtab_from_filename instead of handle_filename. (locate_compound_sym): Rename from locate_class_sym. Search in such a way that we find namespace symbols, too. (examine_compound_token): Call locate_class_sym instead of locate_compound_sym. (locate_compound_sym): Add NAMESPACE arg. (examine_compound_token): New arg to locate_compound_sym. Handle TYPE_CODE_NAMESPACE. #include "cp-support.hp" --- gdb/ChangeLog | 29 ++++++++ gdb/Makefile.in | 2 +- gdb/buildsym.c | 28 ++++---- gdb/cp-support.c | 74 +++++++++++--------- gdb/cp-support.h | 2 +- gdb/linespec.c | 200 +++++++++++++++++++++++++++++++++++++++---------------- gdb/symtab.c | 5 +- gdb/valops.c | 12 ++-- 8 files changed, 238 insertions(+), 114 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 05c3f0c2a67..817f79e5170 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,32 @@ +2003-02-12 David Carlton + + * linespec.c (examine_compound_token): Call decode_namespace. + (decode_namespace): New function. + * cp-support.c (cp_find_first_component): Return the offset, not a + pointer. + (check_possible_namespace_symbols_loop): Update call to + cp_find_first_component. + (cp_check_possible_namespace_symbols): Ditto. + (cp_func_name): Ditto. + * buildsym.c (scan_for_anonymous_namespaces): Ditto. + (finish_block): Ditto. + * linespec.c (examine_compound_token): Ditto. + * symtab.c (lookup_symbol_aux_using_loop): Ditto. + * valops.c (find_oload_champ_namespace_loop): Ditto. + * cp-support.h: Declare cp_find_first_component to return an int. + * Makefile.in (linespec.o): cp_support_h. + * linespec.c (symtab_from_filename): Rename from handle_filename. + (decode_line_1): Call symtab_from_filename instead of + handle_filename. + (locate_compound_sym): Rename from locate_class_sym. Search in + such a way that we find namespace symbols, too. + (examine_compound_token): Call locate_class_sym instead of + locate_compound_sym. + (locate_compound_sym): Add NAMESPACE arg. + (examine_compound_token): New arg to locate_compound_sym. + Handle TYPE_CODE_NAMESPACE. + #include "cp-support.hp" + 2003-02-11 David Carlton * valops.c (find_oload_champ): Add comment. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 774b93b51d4..f716b9e9d80 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1842,7 +1842,7 @@ lin-lwp.o: lin-lwp.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(gdb_wait_h) \ $(gdbthread_h) $(inferior_h) $(target_h) $(regcache_h) $(gdbcmd_h) linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \ $(symfile_h) $(objfiles_h) $(demangle_h) $(value_h) $(completer_h) \ - $(cp_abi_h) $(source_h) $(block_h) $(parser_defs_h) + $(cp_abi_h) $(source_h) $(block_h) $(parser_defs_h) $(cp_support_h) linux-proc.o: linux-proc.c $(defs_h) $(inferior_h) $(regcache_h) \ $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(elf_bfd_h) \ $(cli_decode_h) $(gdb_string_h) diff --git a/gdb/buildsym.c b/gdb/buildsym.c index bff208d5b48..1ef8ea4b959 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -162,8 +162,9 @@ static void scan_for_anonymous_namespaces (struct symbol *symbol) { const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol); - const char *beginning; - const char *end; + int old_index; + int new_index; + const char *len; /* Start with a quick-and-dirty check for mention of "(anonymous namespace)". */ @@ -171,13 +172,13 @@ scan_for_anonymous_namespaces (struct symbol *symbol) if (!cp_is_anonymous (name, -1)) return; - beginning = name; - end = cp_find_first_component (beginning); + old_index = 0; + new_index = cp_find_first_component (name + old_index); - while (*end == ':') + while (name[new_index] == ':') { - if ((end - beginning) == ANONYMOUS_NAMESPACE_LEN - && strncmp (beginning, "(anonymous namespace)", + if ((new_index - old_index) == ANONYMOUS_NAMESPACE_LEN + && strncmp (name + old_index, "(anonymous namespace)", ANONYMOUS_NAMESPACE_LEN) == 0) { /* We've found a component of the name that's an anonymous @@ -185,12 +186,12 @@ scan_for_anonymous_namespaces (struct symbol *symbol) 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); + old_index == 0 ? 0 : old_index - 2, + new_index); } /* The "+ 2" is for the "::". */ - beginning = end + 2; - end = cp_find_first_component (beginning); + old_index = new_index + 2; + new_index = old_index + cp_find_first_component (name + old_index); } } @@ -455,12 +456,13 @@ finish_block (struct symbol *symbol, struct pending **listhead, think that's a problem yet, but it will be. */ current = name; - next = cp_find_first_component (current); + next = current + cp_find_first_component (current); while (*next == ':') { current = next; /* The '+ 2' is to skip the '::'. */ - next = cp_find_first_component (current + 2); + next = current + 2; + next += cp_find_first_component (next); } if (current == name) block_set_scope (block, "", &objfile->symbol_obstack); diff --git a/gdb/cp-support.c b/gdb/cp-support.c index ecdbabb031c..a32b1832a70 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -320,66 +320,76 @@ cp_free_usings (struct using_direct_node *using) #define LENGTH_OF_OPERATOR 8 -const char * -cp_find_first_component (const char *name) +int +cp_find_first_component (const char *const name) { /* Names like 'operator<<' screw up the recursion, so let's special-case them. I _hope_ they can only occur at the start of a component. */ + int index = 0; + if (strncmp (name, "operator", LENGTH_OF_OPERATOR) == 0) { - name += LENGTH_OF_OPERATOR; - switch (*name) + index += LENGTH_OF_OPERATOR; + switch (name[index]) { case '<': - if (name[1] == '<') - name += 2; + if (name[index + 1] == '<') + index += 2; else - name += 1; + index += 1; break; case '>': case '-': - if (name[1] == '>') - name +=2; + if (name[index + 1] == '>') + index += 2; else - name += 1; + index += 1; break; case '(': - name += 2; + index += 2; break; default: - name += 1; + index += 1; break; } } - for (;; ++name) + for (;; ++index) { - switch (*name) + switch (name[index]) { case '<': /* Template; eat it up. The calls to cp_first_component should only return (I hope!) when they reach the '>' terminating the component or a '::' between two components. (Hence the '+ 2'.) */ - for (name = cp_find_first_component (name + 1); - *name != '>'; - name = cp_find_first_component (name + 2)) - gdb_assert (*name == ':'); + index += 1; + for (index += cp_find_first_component (name + index); + name[index] != '>'; + index += cp_find_first_component (name + index)) + { + gdb_assert (name[index] == ':'); + index += 2; + } break; case '(': /* Similar comment as to '<'. */ - for (name = cp_find_first_component (name + 1); - *name != ')'; - name = cp_find_first_component (name + 2)) - gdb_assert (*name == ':'); + index += 1; + for (index += cp_find_first_component (name + index); + name[index] != ')'; + index += cp_find_first_component (name + index)) + { + gdb_assert (name[index] == ':'); + index += 2; + } break; case '>': case ')': case '\0': case ':': - return name; + return index; default: break; } @@ -590,14 +600,17 @@ check_possible_namespace_symbols_loop (const char *name, int len) { if (name[len] == ':') { - const char *next_name = cp_find_first_component (name + len + 2); - int done = check_possible_namespace_symbols_loop (name, - next_name - name); + int done; + int next_len = len + 2; + + next_len += cp_find_first_component (name + next_len); + done = check_possible_namespace_symbols_loop (name, next_len); if (!done) { done = check_one_possible_namespace_symbol (name, len); } + return done; } else @@ -612,8 +625,7 @@ void cp_check_possible_namespace_symbols (const char *name) { check_possible_namespace_symbols_loop (name, - cp_find_first_component (name) - - name); + cp_find_first_component (name)); } /* Look for a symbol in possible_namespace_block named NAME. */ @@ -679,9 +691,11 @@ cp_func_name (const char *full_name) if (!full_name) return NULL; - for (next_component = cp_find_first_component (previous_component); + for (next_component = (previous_component + + cp_find_first_component (previous_component)); *next_component == ':'; - next_component = cp_find_first_component (previous_component)) + next_component = (previous_component + + cp_find_first_component (previous_component))) { /* Skip '::'. */ previous_component = next_component + 2; diff --git a/gdb/cp-support.h b/gdb/cp-support.h index 1bf2f78f89f..9d8d315485d 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -30,7 +30,7 @@ extern char *class_name_from_physname (const char *physname); extern char *method_name_from_physname (const char *physname); -extern const char *cp_find_first_component (const char *name); +extern int cp_find_first_component (const char *name); /* This is a struct to store data from "using directives" and similar language constructs. NAME is a pointer to a string; its initial diff --git a/gdb/linespec.c b/gdb/linespec.c index 1db423b5dd4..94b6a5e69b8 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -33,6 +33,7 @@ #include "cp-abi.h" #include "block.h" #include "parser-defs.h" +#include "cp-support.h" /* Prototypes for local functions. */ @@ -60,7 +61,15 @@ static int examine_compound_token (char **argptr, char *p, struct symtabs_and_lines *values); -static struct symbol *locate_class_sym (char **argptr, char *p); +static struct symbol *locate_compound_sym (char **argptr, + char *current_component, + const char *namespace); + +static int decode_namespace (char **argptr, int funfirstline, + char ***canonical, + char *next_component, + const char *namespace, + struct symtabs_and_lines *values); static char *find_next_token (char **argptr); @@ -106,8 +115,9 @@ static NORETURN void cplusplus_error (const char *name, const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 2, 3); -static struct symtab *handle_filename (char **argptr, char *filename_end, - int is_quote_enclosed); +static struct symtab *symtab_from_filename (char **argptr, + char *filename_end, + int is_quote_enclosed); static int is_all_digits (char *arg); @@ -263,7 +273,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, /* No, the first part is a filename; set file_symtab accordingly. Also, move argptr past the filename. */ - file_symtab = handle_filename (argptr, p, is_quote_enclosed); + file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed); } } @@ -664,78 +674,149 @@ examine_compound_token (char **argptr, int funfirstline, char *saved_arg, char *current_component, struct symtabs_and_lines *values) { - char *copy; - struct symbol *class_sym; - struct type *t; - - /* If CURRENT_COMPONENT points at the end of a name of a class, find - the corresponding symbol and advance ARGPTR past the end of the - class. */ + const char *namespace = ""; + + while (1) + { + char *copy; + struct symbol *class_sym; + struct type *t; - class_sym = locate_class_sym (argptr, current_component); + /* If CURRENT_COMPONENT points at the end of a name of a class + or namespace, find the corresponding symbol and advance + ARGPTR past the end of the class/namespace. */ - if (class_sym == NULL) - return 0; + class_sym = locate_compound_sym (argptr, current_component, namespace); - t = check_typedef (SYMBOL_TYPE (class_sym)); + if (class_sym == NULL) + return 0; - switch (TYPE_CODE (t)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - /* Find the next token (everything up to end or next blank). */ - - current_component = find_next_token (argptr); - copy = alloca (current_component - *argptr + 1); - memcpy (copy, *argptr, current_component - *argptr); - copy[current_component - *argptr] = '\0'; - if (current_component != *argptr - && copy[current_component - *argptr - 1] - && (strchr (get_gdb_completer_quote_characters (), - copy[current_component - *argptr - 1]) - != NULL)) - copy[current_component - *argptr - 1] = '\0'; + t = check_typedef (SYMBOL_TYPE (class_sym)); + + switch (TYPE_CODE (t)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + /* Find the next token (everything up to end or next blank). */ + + current_component = find_next_token (argptr); + copy = alloca (current_component - *argptr + 1); + memcpy (copy, *argptr, current_component - *argptr); + copy[current_component - *argptr] = '\0'; + if (current_component != *argptr + && copy[current_component - *argptr - 1] + && (strchr (get_gdb_completer_quote_characters (), + copy[current_component - *argptr - 1]) + != NULL)) + copy[current_component - *argptr - 1] = '\0'; - while (*current_component == ' ' || *current_component == '\t') - current_component++; - *argptr = current_component; + while (*current_component == ' ' || *current_component == '\t') + current_component++; + *argptr = current_component; - *values = find_method (funfirstline, canonical, saved_arg, copy, - t, class_sym); + *values = find_method (funfirstline, canonical, saved_arg, copy, + t, class_sym); - return 1; - case TYPE_CODE_NAMESPACE: - return 0; - default: - /* FIXME: carlton/2002-11-19: Once this all settles down, this - case should be an error rather than a return 0; that will - allow us to make VALUES the return value rather than an - argument. */ - return 0; + return 1; + case TYPE_CODE_NAMESPACE: + { + char *next_component = find_next_token (argptr); + namespace = TYPE_TAG_NAME (t); + if (*next_component == ':') + { + current_component = next_component; + break; + } + else + { + return decode_namespace (argptr, funfirstline, + canonical, + next_component, namespace, + values); + } + } + default: + /* FIXME: carlton/2002-11-19: Once this all settles down, this + case should be an error rather than a return 0; that will + allow us to make VALUES the return value rather than an + argument. */ + return 0; + } } } +/* Locate a symbol associated to a class/namespace that starts at + *argptr and ends at current_component, looking for it in the + namespace NAMESPACE. Advance *ARGPTR to the start of the next + component. It's the caller's responsibility to verify that the + symbol in question is non-NULL and of the correct type. */ + static struct symbol * -locate_class_sym (char **argptr, char *p) +locate_compound_sym (char **argptr, char *current_component, + const char *namespace) { char *p1; char *copy; - /* Extract the class name. */ - p1 = p; - while (p != *argptr && p[-1] == ' ') - --p; - copy = alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = 0; + /* Extract the class/namespace name. */ + p1 = current_component; + while (current_component != *argptr && current_component[-1] == ' ') + --current_component; + copy = alloca (current_component - *argptr + 1); + memcpy (copy, *argptr, current_component - *argptr); + copy[current_component - *argptr] = 0; /* Discard the class name from the arg. */ - p = p1 + (p1[0] == ':' ? 2 : 1); - while (*p == ' ' || *p == '\t') - p++; - *argptr = p; + current_component = p1 + (p1[0] == ':' ? 2 : 1); + while (*current_component == ' ' || *current_component == '\t') + current_component++; + *argptr = current_component; + + return lookup_symbol_namespace (namespace, strlen (namespace), + copy, NULL, get_selected_block(0), + VAR_NAMESPACE, NULL); +} + +/* Try to look up the symbol in the namespace NAMESPACE whose name + starts at *ARGPTR and ends at *NEXT_COMPONENT. If successful, + return 1 and store an appropriate symtabs_and_lines in VALUES; + otherwise, return 0. */ + +/* FIXME: carlton/2003-02-12: The only reason for not just returning + the symtabs_and_lines directly (and signalling an error if an + appropriate one can't be produced) is because + examine_compound_token wants it for historical reasons; I sure + don't like it. */ + +static int +decode_namespace (char **argptr, int funfirstline, + char ***canonical, + char *next_component, const char *namespace, + struct symtabs_and_lines *values) +{ + char *copy; + struct symbol *sym; + struct symtab *sym_symtab; + + copy = alloca (next_component - *argptr + 1); + memcpy (copy, *argptr, next_component - *argptr); + copy[next_component - *argptr] = '\0'; + *argptr = next_component; - return lookup_symbol (copy, NULL, STRUCT_NAMESPACE, NULL, NULL); + sym = lookup_symbol_namespace (namespace, strlen (namespace), + copy, NULL, get_selected_block(0), + VAR_NAMESPACE, &sym_symtab); + + if (sym != NULL) + { + *values = symbol_found (funfirstline, canonical, copy, + sym, NULL, sym_symtab); + return 1; + } + else + { + return 0; + } } /* Find the next token (presumably a method name); if some of it is @@ -1262,7 +1343,8 @@ cplusplus_error (const char *name, const char *fmt, ...) of *ARGPTR ending at FILE_NAME_END. */ static struct symtab * -handle_filename (char **argptr, char *filename_end, int is_quote_enclosed) +symtab_from_filename (char **argptr, char *filename_end, + int is_quote_enclosed) { char *saved_filename_end; char *copy; diff --git a/gdb/symtab.c b/gdb/symtab.c index a277efbd025..3ee6a6b3c13 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1290,7 +1290,6 @@ lookup_symbol_aux_using_loop (const char *name, 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. */ @@ -1299,9 +1298,9 @@ lookup_symbol_aux_using_loop (const char *name, gdb_assert (scope[new_scope_len] == ':'); new_scope_len += 2; } - next_component = cp_find_first_component (scope + new_scope_len) - scope; + new_scope_len += cp_find_first_component (scope + new_scope_len); sym = lookup_symbol_aux_using_loop (name, linkage_name, block, namespace, - symtab, scope, next_component); + symtab, scope, new_scope_len); if (sym != NULL) return sym; } diff --git a/gdb/valops.c b/gdb/valops.c index 0482cec532f..2525394dc27 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -2939,8 +2939,7 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs, struct badness_vector **oload_champ_bv, int *oload_champ) { - int modified_namespace_len = namespace_len; - int next_namespace_len; + int next_namespace_len = namespace_len; int searched_deeper = 0; int num_fns = 0; struct cleanup *old_cleanups; @@ -2948,14 +2947,13 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs, struct symbol **new_oload_syms; struct badness_vector *new_oload_champ_bv; - if (modified_namespace_len != 0) + if (next_namespace_len != 0) { - gdb_assert (qualified_name[modified_namespace_len] == ':'); - modified_namespace_len += 2; + gdb_assert (qualified_name[next_namespace_len] == ':'); + next_namespace_len += 2; } next_namespace_len - = (cp_find_first_component (qualified_name + modified_namespace_len) - - qualified_name); + += cp_find_first_component (qualified_name + next_namespace_len); /* Initialize these to values that can safely be xfree'd. */ *oload_syms = NULL; -- cgit v1.2.1