public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-tromey-ambiguous-linespec: make "break function:label" work with multiple matches this still has a FIXME: I'm not sure if the canonicalization stuff is all correct
@ 2011-08-05 21:09 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2011-08-05 21:09 UTC (permalink / raw)
  To: archer-commits

The branch, archer-tromey-ambiguous-linespec has been updated
       via  9ca0a7d8965feecffed6e2d5ac71c2d56044db14 (commit)
       via  cc237c12595a3ffda3cac980ae6135adba655d41 (commit)
      from  d0fbe192166f55926023e0dc3e6bf980b5587371 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 9ca0a7d8965feecffed6e2d5ac71c2d56044db14
Author: Tom Tromey <tromey@redhat.com>
Date:   Fri Aug 5 15:08:46 2011 -0600

    make "break function:label" work with multiple matches
    this still has a FIXME: I'm not sure if the canonicalization
    stuff is all correct

commit cc237c12595a3ffda3cac980ae6135adba655d41
Author: Tom Tromey <tromey@redhat.com>
Date:   Fri Aug 5 13:32:12 2011 -0600

    use skip_spaces where appropriate

-----------------------------------------------------------------------

Summary of changes:
 gdb/linespec.c                                |  265 +++++++++++++++----------
 gdb/testsuite/gdb.linespec/base/two/thefile.c |    2 +-
 gdb/testsuite/gdb.linespec/linespec.exp       |    4 +
 gdb/testsuite/gdb.linespec/lspec.c            |    2 +-
 4 files changed, 165 insertions(+), 108 deletions(-)

First 500 lines of diff:
diff --git a/gdb/linespec.c b/gdb/linespec.c
index af4a935..45b8d60 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -47,6 +47,9 @@
 typedef struct symtab *symtab_p;
 DEF_VEC_P (symtab_p);
 
+typedef struct symbol *symbolp;
+DEF_VEC_P (symbolp);
+
 /* An instance of this is used to keep all state while linespec
    operates.  This instance is passed around as a 'this' pointer to
    the various implementation methods.  */
@@ -68,6 +71,10 @@ struct linespec_state
      copy of "FILE".  */
   char *user_filename;
 
+  /* If the linespec is "FUNCTION:LABEL", this holds an xmalloc'd copy
+     of "FUNCTION".  */
+  char *user_function;
+
   /* The 'funfirstline' value that was passed in to decode_line_1 or
      decode_line_full.  */
   int funfirstline;
@@ -135,8 +142,9 @@ static VEC (symtab_p) *symtab_from_filename (char **argptr,
 					     char *p, int is_quote_enclosed,
 					     char **user_filename);
 
-static struct symbol *find_function_symbol (char **argptr, char *p,
-					    int is_quote_enclosed);
+static VEC (symbolp) *find_function_symbols (char **argptr, char *p,
+					     int is_quote_enclosed,
+					     char **user_function);
 
 static struct symtabs_and_lines decode_all_digits (struct linespec_state *self,
 						   char **argptr,
@@ -145,8 +153,9 @@ static struct symtabs_and_lines decode_all_digits (struct linespec_state *self,
 static struct symtabs_and_lines decode_dollar (struct linespec_state *self,
 					       char *copy);
 
-static int decode_label (struct symbol *function_symbol,
-			 char *copy, struct linespec_result *canonical,
+static int decode_label (struct linespec_state *self,
+			 VEC (symbolp) *function_symbols,
+			 char *copy,
 			 struct symtabs_and_lines *result);
 
 static struct symtabs_and_lines decode_variable (struct linespec_state *self,
@@ -212,6 +221,36 @@ cplusplus_error (const char *name, const char *fmt, ...)
   throw_error (NOT_FOUND_ERROR, "%s", message);
 }
 
+/* A helper that walks over all matching symtabs in all objfiles and
+   calls CALLBACK for each symbol matching NAME.  */
+
+static void
+iterate_over_all_matching_symtabs (const char *name,
+				   const domain_enum domain,
+				   int (*callback) (struct symbol *, void *),
+				   void *data)
+{
+  struct objfile *objfile;
+
+  ALL_OBJFILES (objfile)
+  {
+    struct symtab *symtab;
+
+    if (objfile->sf)
+      objfile->sf->qf->expand_symtabs_for_function (objfile, name);
+
+    ALL_OBJFILE_SYMTABS (objfile, symtab)
+      {
+	if (symtab->primary)
+	  {
+	    struct block *block;
+	    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+	    iterate_over_symbols (block, name, domain, callback, data);
+	  }
+      }
+  }
+}
+
 /* 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
@@ -698,9 +737,7 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline,
 	    }
 	}
 
-      args = arg1;
-      while (*args == ' ' || *args == '\t')
-	args++;
+      args = skip_spaces (arg1);
     }
   return_values.nelts = i;
   discard_cleanups (old_chain);
@@ -864,10 +901,10 @@ decode_line_internal (struct linespec_state *self, char **argptr)
   /* The "first half" of the linespec.  */
   char *first_half;
 
-  /* If we are parsing `function:label', this holds the symbol for the
-     function.  */
-  struct symbol *function_symbol = NULL;
-  /* If FUNCTION_SYMBOL is not NULL, then this is the exception that
+  /* If we are parsing `function:label', this holds the symbols
+     matching the function name.  */
+  VEC (symbolp) *function_symbols = NULL;
+  /* If FUNCTION_SYMBOLS is not NULL, then this is the exception that
      was thrown when trying to parse a filename.  */
   volatile struct gdb_exception file_exception;
 
@@ -987,12 +1024,16 @@ decode_line_internal (struct linespec_state *self, char **argptr)
 	     then check whether we were really given `function:label'.   */
 	  if (file_exception.reason < 0)
 	    {
-	      function_symbol = find_function_symbol (argptr, p,
-						      is_quote_enclosed);
+	      function_symbols = find_function_symbols (argptr, p,
+							is_quote_enclosed,
+							&self->user_function);
+
 	      /* If we did not find a function, re-throw the original
 		 exception.  */
-	      if (!function_symbol)
+	      if (!function_symbols)
 		throw_exception (file_exception);
+
+	      make_cleanup (VEC_cleanup (symbolp), &function_symbols);
 	    }
 
 	  /* Check for single quotes on the non-filename part.  */
@@ -1009,8 +1050,8 @@ decode_line_internal (struct linespec_state *self, char **argptr)
 
   /* self->file_symtabs holds the  specified file symtabs, or 0 if no file
      specified.
-     If we are parsing `function:symbol', then FUNCTION_SYMBOL is the
-     function before the `:'.
+     If we are parsing `function:symbol', then FUNCTION_SYMBOLS holds the
+     functions before the `:'.
      arg no longer contains the file name.  */
 
   /* If the filename was quoted, we must re-check the quotation.  */
@@ -1033,7 +1074,7 @@ decode_line_internal (struct linespec_state *self, char **argptr)
     q++;
 
   if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ',')
-      && function_symbol == NULL)
+      && function_symbols == NULL)
     /* We found a token consisting of all digits -- at least one digit.  */
     return decode_all_digits (self, argptr, q);
 
@@ -1075,15 +1116,14 @@ decode_line_internal (struct linespec_state *self, char **argptr)
     }
   else if (is_quoted || is_squote_enclosed)
     copy[p - *argptr - 1] = '\0';
-  while (*p == ' ' || *p == '\t')
-    p++;
-  *argptr = p;
+  
+  *argptr = skip_spaces (p);
 
   /* If it starts with $: may be a legitimate variable or routine name
      (e.g. HP-UX millicode routines such as $$dyncall), or it may
      be history value, or it may be a convenience variable.  */
 
-  if (*copy == '$' && function_symbol == NULL)
+  if (*copy == '$' && function_symbols == NULL)
     return decode_dollar (self, copy);
 
   /* Try the token as a label, but only if no file was specified,
@@ -1093,11 +1133,11 @@ decode_line_internal (struct linespec_state *self, char **argptr)
       && VEC_index (symtab_p, self->file_symtabs, 0) == NULL)
     {
       struct symtabs_and_lines label_result;
-      if (decode_label (function_symbol, copy, self->canonical, &label_result))
+      if (decode_label (self, function_symbols, copy, &label_result))
 	return label_result;
     }
 
-  if (function_symbol)
+  if (function_symbols)
     throw_exception (file_exception);
 
   /* Look up that token as a variable.
@@ -1130,6 +1170,7 @@ linespec_state_destructor (void *arg)
   struct linespec_state *self = arg;
 
   xfree (self->user_filename);
+  xfree (self->user_function);
   VEC_free (symtab_p, self->file_symtabs);
 }
 
@@ -1333,8 +1374,7 @@ locate_first_half (char **argptr, int *is_quote_enclosed)
 	  break;
 	}
     }
-  while (p[0] == ' ' || p[0] == '\t')
-    p++;
+  p = skip_spaces (p);
 
   /* If the closing double quote was left at the end, remove it.  */
   if (*is_quote_enclosed)
@@ -1671,9 +1711,7 @@ decode_compound (struct linespec_state *self,
       /* At this point copy->"fun", p->"".  */
 
       /* No line number may be specified.  */
-      while (*p == ' ' || *p == '\t')
-	p++;
-      *argptr = p;
+      *argptr = skip_spaces (p);
       /* At this point arptr->"".  */
 
       /* Look for copy as a method of sym_class.  */
@@ -1751,8 +1789,7 @@ lookup_prefix_sym (char **argptr, char *p, struct symtab *file_symtab)
 
   /* Discard the class name from the argptr.  */
   p = p1 + (p1[0] == ':' ? 2 : 1);
-  while (*p == ' ' || *p == '\t')
-    p++;
+  p = skip_spaces (p);
   *argptr = p;
 
   /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
@@ -1995,10 +2032,7 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
     }
 
   /* Discard the file name from the arg.  */
-  p = p1 + 1;
-  while (*p == ' ' || *p == '\t')
-    p++;
-  *argptr = p;
+  *argptr = skip_spaces (p1 + 1);
 
   do_cleanups (cleanups);
   discard_cleanups (outer);
@@ -2006,22 +2040,38 @@ symtab_from_filename (char **argptr, char *p, int is_quote_enclosed,
   return collector.symtabs;
 }
 
+/* A callback used by iterate_over_all_matching_symtabs that collects
+   symbols for find_function_symbols.  */
+
+static int
+collect_function_symbols (struct symbol *sym, void *arg)
+{
+  VEC (symbolp) **syms = arg;
+
+  if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+    VEC_safe_push (symbolp, *syms, sym);
+
+  return 1;
+}
+
 /* Look up a function symbol in *ARGPTR.  If found, advance *ARGPTR
    and return the symbol.  If not found, return NULL.  */
 
-static struct symbol *
-find_function_symbol (char **argptr, char *p, int is_quote_enclosed)
+static VEC (symbolp) *
+find_function_symbols (char **argptr, char *p, int is_quote_enclosed,
+		       char **user_function)
 {
   char *p1;
   char *copy;
-  struct symbol *function_symbol;
+  VEC (symbolp) *result = NULL;
 
   p1 = p;
   while (p != *argptr && p[-1] == ' ')
     --p;
   if ((*p == '"') && is_quote_enclosed)
     --p;
-  copy = (char *) alloca (p - *argptr + 1);
+  copy = (char *) xmalloc (p - *argptr + 1);
+  *user_function = copy;
   memcpy (copy, *argptr, p - *argptr);
   /* It may have the ending quote right after the file name.  */
   if ((is_quote_enclosed && copy[p - *argptr - 1] == '"')
@@ -2030,18 +2080,16 @@ find_function_symbol (char **argptr, char *p, int is_quote_enclosed)
   else
     copy[p - *argptr] = 0;
 
-  function_symbol = lookup_symbol (copy, get_selected_block (0),
-				   VAR_DOMAIN, 0);
-  if (!function_symbol || SYMBOL_CLASS (function_symbol) != LOC_BLOCK)
-    return NULL;
+  iterate_over_all_matching_symtabs (copy, VAR_DOMAIN,
+				     collect_function_symbols, &result);
 
-  /* Discard the file name from the arg.  */
-  p = p1 + 1;
-  while (*p == ' ' || *p == '\t')
-    p++;
-  *argptr = p;
+  if (result != NULL)
+    {
+      /* Discard the file name from the arg.  */
+      *argptr = skip_spaces (p1 + 1);
+    }
 
-  return function_symbol;
+  return result;
 }
 
 \f
@@ -2138,9 +2186,7 @@ decode_all_digits (struct linespec_state *self,
       break;		/* No need to adjust val.line.  */
     }
 
-  while (*q == ' ' || *q == '\t')
-    q++;
-  *argptr = q;
+  *argptr = skip_spaces (q);
 
   for (ix = 0; VEC_iterate (symtab_p, self->file_symtabs, ix, elt); ++ix)
     {
@@ -2261,7 +2307,7 @@ decode_dollar (struct linespec_state *self, char *copy)
 
 /* A helper for decode_line_1 that tries to find a label.  The label
    is searched for in the current block.
-   FUNCTION_SYMBOL is the enclosing function; or NULL if none
+   FUNCTION_SYMBOLS is a list of the enclosing functions; or NULL if none
    specified.
    COPY is the name of the label to find.
    CANONICAL is the same as the "canonical" argument to decode_line_1.
@@ -2270,33 +2316,74 @@ decode_dollar (struct linespec_state *self, char *copy)
    This function returns 1 if a label was found, 0 otherwise.  */
 
 static int
-decode_label (struct symbol *function_symbol, char *copy,
-	      struct linespec_result *canonical,
+decode_label (struct linespec_state *self,
+	      VEC (symbolp) *function_symbols, char *copy,
 	      struct symtabs_and_lines *result)
 {
-  struct symbol *sym;
-  struct block *block;
+  struct symbol *fn_sym;
+  int ix;
 
-  if (function_symbol)
-    block = SYMBOL_BLOCK_VALUE (function_symbol);
-  else
+  if (function_symbols == NULL)
     {
-      block = get_selected_block (0);
+      struct block *block = get_selected_block (0);
+      struct symbol *sym;
+
       for (;
 	   block && !BLOCK_FUNCTION (block);
 	   block = BLOCK_SUPERBLOCK (block))
 	;
       if (!block)
 	return 0;
-      function_symbol = BLOCK_FUNCTION (block);
+      fn_sym = BLOCK_FUNCTION (block);
+
+      sym = lookup_symbol (copy, block, LABEL_DOMAIN, 0);
+
+      if (sym != NULL)
+	*result = symbol_found (0, self->canonical, copy, sym, NULL, fn_sym);
+
+      return 1;
     }
 
-  sym = lookup_symbol (copy, block, LABEL_DOMAIN, 0);
+  result->sals = NULL;
+  result->nelts = 0;
 
-  if (sym != NULL)
-    *result = symbol_found (0, canonical, copy, sym, NULL, function_symbol);
+  for (ix = 0; VEC_iterate (symbolp, function_symbols, ix, fn_sym); ++ix)
+    {
+      struct block *block = SYMBOL_BLOCK_VALUE (fn_sym);
+      struct symbol *sym = lookup_symbol (copy, block, LABEL_DOMAIN, 0);
 
-  return sym != NULL;
+      if (sym != NULL)
+	{
+	  struct symtab_and_line sal;
+
+	  symbol_to_sal (&sal, self->funfirstline, copy, sym);
+	  add_sal_to_sals (result, &sal);
+	}
+    }
+
+  if (self->canonical && result->nelts > 0)
+    {
+      self->canonical->pre_expanded = 1;
+      self->canonical->special_display = 1;
+
+      if (self->user_filename)
+	self->canonical->addr_string
+	  = xstrprintf ("%s:%s", self->user_function, copy);
+      else
+	/* FIXME */
+	self->canonical->addr_string = xstrdup (copy);
+
+      self->canonical->canonical = xmalloc (result->nelts * sizeof (char *));
+      for (ix = 0; ix < result->nelts; ++ix)
+	self->canonical->canonical[ix]
+	  = xstrprintf ("%s:%s",
+			self->user_function, copy);
+			/* FIXME */
+			/* SYMBOL_NATURAL_NAME (function_symbol), */
+			/* SYMBOL_NATURAL_NAME (sym)); */
+    }
+
+  return result->nelts > 0;
 }
 
 struct collect_info
@@ -2318,36 +2405,6 @@ collect_symbols (struct symbol *sym, void *data)
   return 1;
 }
 
-/* A helper for decode_variable that walks over all matching symtabs
-   in all objfiles.  */
-
-static void
-iterate_over_all_matching_symtabs (const char *name,
-				   const domain_enum domain,
-				   int (*callback) (struct symbol *, void *),
-				   void *data)
-{
-  struct objfile *objfile;
-
-  ALL_OBJFILES (objfile)
-  {
-    struct symtab *symtab;
-
-    if (objfile->sf)
-      objfile->sf->qf->expand_symtabs_for_function (objfile, name);
-
-    ALL_OBJFILE_SYMTABS (objfile, symtab)
-      {
-	if (symtab->primary)
-	  {
-	    struct block *block;
-	    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
-	    iterate_over_symbols (block, name, domain, callback, data);
-	  }
-      }
-  }
-}
-
 /* Decode a linespec that's a variable.  If FILE_SYMTAB is non-NULL,
    look in that symtab's static variables first.  */ 
 
@@ -2479,9 +2536,10 @@ symbol_found (int funfirstline, struct linespec_result *canonical, char *copy,
       /* Arg is the name of a function.  */
       values.sals = (struct symtab_and_line *)
 	xmalloc (sizeof (struct symtab_and_line));
-      values.sals[0] = find_function_start_sal (sym, funfirstline);
       values.nelts = 1;
 
+      symbol_to_sal (&values.sals[0], funfirstline, copy, sym);
+
       /* Don't use the SYMBOL_LINE; if used at all it points to
 	 the line containing the parameters or thereabouts, not
 	 the first line of code.  */
@@ -2506,12 +2564,8 @@ symbol_found (int funfirstline, struct linespec_result *canonical, char *copy,
 	  values.sals = (struct symtab_and_line *)
 	    xmalloc (sizeof (struct symtab_and_line));
 	  values.nelts = 1;
-	  init_sal (&values.sals[0]);
-	  values.sals[0].symtab = SYMBOL_SYMTAB (sym);
-	  values.sals[0].line = SYMBOL_LINE (sym);
-	  values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym);
-	  values.sals[0].pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
-	  values.sals[0].explicit_pc = 1;
+
+	  symbol_to_sal (&values.sals[0], funfirstline, copy, sym);
 
 	  if (canonical)
 	    {
@@ -2538,10 +2592,9 @@ symbol_found (int funfirstline, struct linespec_result *canonical, char *copy,
 	  values.sals = (struct symtab_and_line *)
 	    xmalloc (sizeof (struct symtab_and_line));
 	  values.nelts = 1;
-	  memset (&values.sals[0], 0, sizeof (values.sals[0]));
-	  values.sals[0].symtab = SYMBOL_SYMTAB (sym);
-	  values.sals[0].line = SYMBOL_LINE (sym);
-	  values.sals[0].pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
+
+	  symbol_to_sal (&values.sals[0], funfirstline, copy, sym);
+
 	  return values;
 	}
       else
diff --git a/gdb/testsuite/gdb.linespec/base/two/thefile.c b/gdb/testsuite/gdb.linespec/base/two/thefile.c
index bab260a..c3c3579 100644
--- a/gdb/testsuite/gdb.linespec/base/two/thefile.c
+++ b/gdb/testsuite/gdb.linespec/base/two/thefile.c
@@ -3,7 +3,7 @@
 
 static int dupname(int y)
 {


hooks/post-receive
--
Repository for Project Archer.


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

only message in thread, other threads:[~2011-08-05 21:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-05 21:09 [SCM] archer-tromey-ambiguous-linespec: make "break function:label" work with multiple matches this still has a FIXME: I'm not sure if the canonicalization stuff is all correct 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).