From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19918 invoked by alias); 19 Aug 2011 15:15:02 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 19868 invoked by uid 306); 19 Aug 2011 15:15:00 -0000 Date: Fri, 19 Aug 2011 15:15:00 -0000 Message-ID: <20110819151500.19853.qmail@sourceware.org> From: tromey@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-tromey-ambiguous-linespec: (mostly) rewrite decode_compound now it first finds candidate symbol names, then it uses the same machinery as decode_variable to find all matches X-Git-Refname: refs/heads/archer-tromey-ambiguous-linespec X-Git-Reftype: branch X-Git-Oldrev: 3cc1560030483e8b41d78abea376560908c0d3ce X-Git-Newrev: 05fb7afd3b8ecc2aed938bd111e2e64045427f43 X-SW-Source: 2011-q3/txt/msg00108.txt.bz2 List-Id: The branch, archer-tromey-ambiguous-linespec has been updated via 05fb7afd3b8ecc2aed938bd111e2e64045427f43 (commit) via 76880b56ff23f78ac1ffc32b119fc88429555c1e (commit) from 3cc1560030483e8b41d78abea376560908c0d3ce (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 05fb7afd3b8ecc2aed938bd111e2e64045427f43 Author: Tom Tromey Date: Fri Aug 19 09:12:33 2011 -0600 (mostly) rewrite decode_compound now it first finds candidate symbol names, then it uses the same machinery as decode_variable to find all matches commit 76880b56ff23f78ac1ffc32b119fc88429555c1e Author: Tom Tromey Date: Thu Aug 18 14:07:41 2011 -0600 make compare_strings public ----------------------------------------------------------------------- Summary of changes: gdb/cli/cli-cmds.c | 10 - gdb/defs.h | 1 + gdb/linespec.c | 554 ++++++++++++++++++++++---------------------------- gdb/python/py-type.c | 14 +- gdb/utils.c | 10 + 5 files changed, 260 insertions(+), 329 deletions(-) First 500 lines of diff: diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 05e20f7..bffd2a7 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -243,16 +243,6 @@ help_command (char *command, int from_tty) help_cmd (command, gdb_stdout); } -/* String compare function for qsort. */ -static int -compare_strings (const void *arg1, const void *arg2) -{ - const char **s1 = (const char **) arg1; - const char **s2 = (const char **) arg2; - - return strcmp (*s1, *s2); -} - /* The "complete" command is used by Emacs to implement completion. */ static void diff --git a/gdb/defs.h b/gdb/defs.h index eaf9c2a..332b8b5 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -419,6 +419,7 @@ char *ldirname (const char *filename); char **gdb_buildargv (const char *); int compare_positive_ints (const void *ap, const void *bp); +int compare_strings (const void *ap, const void *bp); /* A wrapper for bfd_errmsg to produce a more helpful error message in the case of bfd_error_file_ambiguously recognized. diff --git a/gdb/linespec.c b/gdb/linespec.c index 368f596..51a1500 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -50,6 +50,9 @@ DEF_VEC_P (symtab_p); typedef struct symbol *symbolp; DEF_VEC_P (symbolp); +typedef struct type *typep; +DEF_VEC_P (typep); + /* An address entry is used to ensure that any given location is only added to the result a single time. It holds an address and the program space from which the address came. */ @@ -104,7 +107,6 @@ struct collect_info { struct linespec_state *state; struct symtabs_and_lines result; - int funfirstline; /* The current objfile; used only by the minimal symbol code below. */ struct objfile *objfile; @@ -128,29 +130,18 @@ static struct symtabs_and_lines decode_compound (struct linespec_state *self, char *p); static VEC (symbolp) *lookup_prefix_sym (char **argptr, char *p, - VEC (symtab_p) *); + VEC (symtab_p) *, + char **); static struct symtabs_and_lines find_method (struct linespec_state *self, char *saved_arg, char *copy, + const char *class_name, VEC (symbolp) *sym_classes); static void cplusplus_error (const char *name, const char *fmt, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); -static int total_number_of_methods (struct type *type); - -static int find_methods (struct type *, const char *, - enum language, struct symbol **, struct symtab *); - -static int add_matching_methods (int method_counter, struct type *t, - enum language language, - struct symbol **sym_arr); - -static int add_constructors (int method_counter, struct type *t, - enum language language, - struct symbol **sym_arr); - static void build_canonical_line_spec (const struct symtabs_and_lines *, char *, struct linespec_result *); @@ -196,9 +187,10 @@ symtabs_and_lines symbol_found (int funfirstline, struct symtab *file_symtab, struct symbol *function_symbol); -static void add_matching_symbols_to_info (struct linespec_state *self, - const char *name, - struct collect_info *info); +static void add_matching_symbols_to_info (const char *name, + struct collect_info *info, + struct program_space *pspace); + /* Helper functions. */ static void @@ -300,19 +292,25 @@ iterate_name_matcher (const char *name, void *d) } /* A helper that walks over all matching symtabs in all objfiles and - calls CALLBACK for each symbol matching NAME. */ + calls CALLBACK for each symbol matching NAME. If SEARCH_PSPACE is + not NULL, then the search is restricted to just that program + space. */ static void iterate_over_all_matching_symtabs (const char *name, const domain_enum domain, int (*callback) (struct symbol *, void *), - void *data) + void *data, + struct program_space *search_pspace) { struct objfile *objfile; struct program_space *pspace; ALL_PSPACES (pspace) { + if (search_pspace != NULL && search_pspace != pspace) + continue; + set_current_program_space (pspace); ALL_OBJFILES (objfile) @@ -338,28 +336,6 @@ iterate_over_all_matching_symtabs (const char *name, } } -/* Return the number of methods described for TYPE, including the - methods from types it derives from. This can't be done in the symbol - reader because the type of the baseclass might still be stubbed - when the definition of the derived class is parsed. */ - -static int -total_number_of_methods (struct type *type) -{ - int n; - int count; - - CHECK_TYPEDEF (type); - if (! HAVE_CPLUS_STRUCT (type)) - return 0; - count = TYPE_NFN_FIELDS_TOTAL (type); - - for (n = 0; n < TYPE_N_BASECLASSES (type); n++) - count += total_number_of_methods (TYPE_BASECLASS (type, n)); - - return count; -} - /* Returns the block to be used for symbol searches for the given SYMTAB, which may be NULL. */ @@ -384,16 +360,14 @@ get_search_block (struct symtab *symtab) return block; } -/* Recursive helper function for decode_line_1. - Look for methods named NAME in type T. - Return number of matches. - Put matches in SYM_ARR, which should have been allocated with - a size of total_number_of_methods (T) * sizeof (struct symbol *). - Note that this function is g++ specific. */ +/* A helper for find_method. This finds all methods in type T which + match NAME. It adds resulting symbol names to RESULT_NAMES, and + adds T's direct superclasses to SUPERCLASSES. */ -static int -find_methods (struct type *t, const char *name, enum language language, - struct symbol **sym_arr, struct symtab *file_symtab) +static void +find_methods (struct type *t, const char *name, + VEC (const_char_ptr) **result_names, + VEC (typep) **superclasses) { int i1 = 0; int ibase; @@ -403,9 +377,7 @@ find_methods (struct type *t, const char *name, enum language language, /* Ignore this class if it doesn't have a name. This is ugly, but unless we figure out how to get the physname without the name of the class, then the loop can't do any good. */ - if (class_name - && (lookup_symbol_in_language (class_name, get_search_block (file_symtab), - STRUCT_DOMAIN, language, (int *) NULL))) + if (class_name) { int method_counter; int name_len = strlen (name); @@ -434,137 +406,31 @@ find_methods (struct type *t, const char *name, enum language language, } if (strcmp_iw (name, method_name) == 0) - /* Find all the overloaded methods with that name. */ - i1 += add_matching_methods (method_counter, t, language, - sym_arr + i1); - else if (strncmp (class_name, name, name_len) == 0 - && (class_name[name_len] == '\0' - || class_name[name_len] == '<')) - i1 += add_constructors (method_counter, t, language, - sym_arr + i1); - } - } - - /* Only search baseclasses if there is no match yet, since names in - derived classes override those in baseclasses. - - FIXME: The above is not true; it is only true of member functions - if they have the same number of arguments (??? - section 13.1 of the - ARM says the function members are not in the same scope but doesn't - really spell out the rules in a way I understand. In any case, if - the number of arguments differ this is a case in which we can overload - rather than hiding without any problem, and gcc 2.4.5 does overload - rather than hiding in this case). */ - - if (i1 == 0) - for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) - i1 += find_methods (TYPE_BASECLASS (t, ibase), name, - language, sym_arr + i1, file_symtab); - - return i1; -} - -/* Add the symbols associated to methods of the class whose type is T - and whose name matches the method indexed by METHOD_COUNTER in the - array SYM_ARR. Return the number of methods added. */ - -static int -add_matching_methods (int method_counter, struct type *t, - enum language language, struct symbol **sym_arr) -{ - int field_counter; - int i1 = 0; + { + int field_counter; - for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; - field_counter >= 0; - --field_counter) - { - struct fn_field *f; - const char *phys_name; + for (field_counter = (TYPE_FN_FIELDLIST_LENGTH (t, method_counter) + - 1); + field_counter >= 0; + --field_counter) + { + struct fn_field *f; + const char *phys_name; - f = TYPE_FN_FIELDLIST1 (t, method_counter); + f = TYPE_FN_FIELDLIST1 (t, method_counter); + if (TYPE_FN_FIELD_STUB (f, field_counter)) + continue; + phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - if (TYPE_FN_FIELD_STUB (f, field_counter)) - { - char *tmp_name, *tmp2; - - tmp_name = gdb_mangle_name (t, - method_counter, - field_counter); - tmp2 = alloca (strlen (tmp_name) + 1); - strcpy (tmp2, tmp_name); - xfree (tmp_name); - phys_name = tmp2; - } - else - phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - - sym_arr[i1] = lookup_symbol_in_language (phys_name, - NULL, VAR_DOMAIN, - language, - (int *) NULL); - if (sym_arr[i1]) - i1++; - else - { - /* This error message gets printed, but the method - still seems to be found. - fputs_filtered("(Cannot find method ", gdb_stdout); - fprintf_symbol_filtered (gdb_stdout, phys_name, - language_cplus, - DMGL_PARAMS | DMGL_ANSI); - fputs_filtered(" - possibly inlined.)\n", gdb_stdout); - */ + if (strcmp_iw (phys_name, method_name) == 0) + VEC_safe_push (const_char_ptr, *result_names, phys_name); + } + } } } - return i1; -} - -/* Add the symbols associated to constructors of the class whose type - is CLASS_TYPE and which are indexed by by METHOD_COUNTER to the - array SYM_ARR. Return the number of methods added. */ - -static int -add_constructors (int method_counter, struct type *t, - enum language language, struct symbol **sym_arr) -{ - int field_counter; - int i1 = 0; - - /* For GCC 3.x and stabs, constructors and destructors - have names like __base_ctor and __complete_dtor. - Check the physname for now if we're looking for a - constructor. */ - for (field_counter - = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; - field_counter >= 0; - --field_counter) - { - struct fn_field *f; - const char *phys_name; - - f = TYPE_FN_FIELDLIST1 (t, method_counter); - - /* GCC 3.x will never produce stabs stub methods, so - we don't need to handle this case. */ - if (TYPE_FN_FIELD_STUB (f, field_counter)) - continue; - phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); - if (! is_constructor_name (phys_name)) - continue; - - /* If this method is actually defined, include it in the - list. */ - sym_arr[i1] = lookup_symbol_in_language (phys_name, - NULL, VAR_DOMAIN, - language, - (int *) NULL); - if (sym_arr[i1]) - i1++; - } - - return i1; + for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) + VEC_safe_push (typep, *superclasses, TYPE_BASECLASS (t, ibase)); } /* Helper function for decode_line_1. @@ -1592,8 +1458,8 @@ decode_compound (struct linespec_state *self, struct symbol *sym; char *copy; VEC (symbolp) *sym_classes; - char *saved_arg; - struct cleanup *cleanup; + char *saved_arg, *class_name; + struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); /* If the user specified any completer quote characters in the input, strip them. They are superfluous. */ @@ -1729,16 +1595,15 @@ decode_compound (struct linespec_state *self, /* Before the call, argptr->"AAA::inA::fun", p->"", p2->"::fun". After the call: argptr->"fun", p, p2 unchanged. */ - sym_classes = lookup_prefix_sym (argptr, p2, self->file_symtabs); + sym_classes = lookup_prefix_sym (argptr, p2, self->file_symtabs, + &class_name); + make_cleanup (VEC_cleanup (symbolp), &sym_classes); + make_cleanup (xfree, class_name); /* If a class has been found, then we're in case 1 above. So we look up "fun" as a method of those classes. */ if (sym_classes) { - struct cleanup *cleanup; - - cleanup = make_cleanup (VEC_cleanup (symbolp), &sym_classes); - /* Arg token is not digits => try it as a function name. Find the next token (everything up to end or next blank). */ @@ -1797,7 +1662,7 @@ decode_compound (struct linespec_state *self, here, we return. If not, and we are at the and of the string, we'll lookup the whole string in the symbol tables. */ - values = find_method (self, saved_arg, copy, sym_classes); + values = find_method (self, saved_arg, copy, class_name, sym_classes); do_cleanups (cleanup); return values; @@ -1820,7 +1685,6 @@ decode_compound (struct linespec_state *self, /* Look up entire name. */ name = copy; - make_cleanup (null_cleanup, NULL); canon = cp_canonicalize_string_no_typedefs (copy); if (canon != NULL) { @@ -1890,7 +1754,8 @@ collect_one_symbol (struct symbol *sym, void *d) example, say ARGPTR is "AAA::inA::fun" and P is "::inA::fun". */ static VEC (symbolp) * -lookup_prefix_sym (char **argptr, char *p, VEC (symtab_p) *file_symtabs) +lookup_prefix_sym (char **argptr, char *p, VEC (symtab_p) *file_symtabs, + char **class_name) { char *p1; char *copy; @@ -1905,9 +1770,11 @@ lookup_prefix_sym (char **argptr, char *p, VEC (symtab_p) *file_symtabs) p1 = p; while (p != *argptr && p[-1] == ' ') --p; - copy = (char *) alloca (p - *argptr + 1); + copy = (char *) xmalloc (p - *argptr + 1); memcpy (copy, *argptr, p - *argptr); copy[p - *argptr] = 0; + *class_name = copy; + outer = make_cleanup (xfree, copy); /* Discard the class name from the argptr. */ p = p1 + (p1[0] == ':' ? 2 : 1); @@ -1918,7 +1785,7 @@ lookup_prefix_sym (char **argptr, char *p, VEC (symtab_p) *file_symtabs) argptr->"inA::fun". */ collector.symbols = NULL; - outer = make_cleanup (VEC_cleanup (symbolp), &collector.symbols); + make_cleanup (VEC_cleanup (symbolp), &collector.symbols); collector.unique_syms = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer, NULL, @@ -1930,9 +1797,11 @@ lookup_prefix_sym (char **argptr, char *p, VEC (symtab_p) *file_symtabs) if (elt == NULL) { iterate_over_all_matching_symtabs (copy, STRUCT_DOMAIN, - collect_one_symbol, &collector); + collect_one_symbol, &collector, + NULL); iterate_over_all_matching_symtabs (copy, VAR_DOMAIN, - collect_one_symbol, &collector); + collect_one_symbol, &collector, + NULL); } else { @@ -1952,29 +1821,100 @@ lookup_prefix_sym (char **argptr, char *p, VEC (symtab_p) *file_symtabs) return collector.symbols; } -/* This finds the method COPY in the class whose type is T and whose - symbol is SYM_CLASS. */ +/* A qsort comparison function for symbols. The resulting order does + not actually matter; we just need to be able to sort them so that + symbols with the same program space end up next to each other. */ + +static int +compare_symbols (const void *a, const void *b) +{ + struct symbol * const *sa = a; + struct symbol * const *sb = b; + uintptr_t uia, uib; + + uia = (uintptr_t) SYMTAB_PSPACE (SYMBOL_SYMTAB (*sa)); + uib = (uintptr_t) SYMTAB_PSPACE (SYMBOL_SYMTAB (*sb)); + + if (uia < uib) + return -1; + if (uia > uib) + return 1; + + uia = (uintptr_t) *sa; + uib = (uintptr_t) *sb; + + if (uia < uib) + return -1; + if (uia > uib) + return 1; + + return 0; +} + +/* Look for all the matching instances of each symbol in NAMES. Only + instances from PSPACE are considered; other program spaces are + handled by our caller. Results are stored into INFO. */ + +static void +add_all_symbol_names_from_pspace (struct collect_info *info, + struct program_space *pspace, + VEC (const_char_ptr) *names) +{ + int ix; + const char *iter; + + gdb_assert (pspace != NULL); + + for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix) + add_matching_symbols_to_info (iter, info, pspace); +} + hooks/post-receive -- Repository for Project Archer.