public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [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
@ 2011-08-19 15:15 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2011-08-19 15:15 UTC (permalink / raw)
  To: archer-commits

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 <tromey@redhat.com>
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 <tromey@redhat.com>
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);
 }
 \f
-/* 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.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-19 15:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-19 15:15 [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 tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).