add1a2d
[base]
add1a2d
add1a2d
2007-09-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
add1a2d
add1a2d
	* linespec.c (add_minsym_members): Support also the `$allocate' and
add1a2d
	`$delete' variants.
add1a2d
cafa2ff
2007-10-05  Jan Kratochvil  <jan.kratochvil@redhat.com>
cafa2ff
cafa2ff
	* linespec.c (add_minsym_members): Support also the `$allocate' and
cafa2ff
	`$delete' variants.
cafa2ff
	(decode_variable): Renamed to ...
cafa2ff
	(decode_variable_1) ... here, its parameter NOT_FOUND_PTR and its
cafa2ff
	exception throwing was moved to ...
cafa2ff
	(decode_variable_not_found): ... a new function here.
cafa2ff
	(decode_variable): New function.
cafa2ff
eb9d945
2007-10-31  Jan Kratochvil  <jan.kratochvil@redhat.com>
eb9d945
eb9d945
	Port to GDB-6.7.
eb9d945
eb9d945
Index: gdb-6.7/gdb/linespec.c
9231e41
===================================================================
eb9d945
--- gdb-6.7.orig/gdb/linespec.c	2007-08-23 20:08:35.000000000 +0200
eb9d945
+++ gdb-6.7/gdb/linespec.c	2007-10-13 05:26:33.000000000 +0200
eb9d945
@@ -36,6 +36,7 @@
cafa2ff
 #include "linespec.h"
cafa2ff
 #include "exceptions.h"
eb9d945
 #include "language.h"
cafa2ff
+#include "gdb_assert.h"
cafa2ff
 
cafa2ff
 /* We share this one with symtab.c, but it is not exported widely. */
cafa2ff
 
eb9d945
@@ -75,7 +76,8 @@ static struct symtabs_and_lines find_met
8e71796
 
8e71796
 static int collect_methods (char *copy, struct type *t,
eb9d945
 			    struct symbol *sym_class,
8e71796
-			    struct symbol **sym_arr);
8e71796
+			    struct symbol **sym_arr,
8e71796
+			    struct minimal_symbol **msym_arr);
8e71796
 
8e71796
 static NORETURN void cplusplus_error (const char *name,
8e71796
 				      const char *fmt, ...)
eb9d945
@@ -84,11 +86,13 @@ static NORETURN void cplusplus_error (co
8e71796
 static int total_number_of_methods (struct type *type);
8e71796
 
eb9d945
 static int find_methods (struct type *, char *,
eb9d945
-			 enum language, struct symbol **);
eb9d945
+			 enum language, struct symbol **,
8e71796
+			 struct minimal_symbol **);
8e71796
 
8e71796
 static int add_matching_methods (int method_counter, struct type *t,
eb9d945
 				 enum language language,
8e71796
-				 struct symbol **sym_arr);
8e71796
+				 struct symbol **sym_arr,
8e71796
+				 struct minimal_symbol **msym_arr);
8e71796
 
8e71796
 static int add_constructors (int method_counter, struct type *t,
eb9d945
 			     enum language language,
eb9d945
@@ -104,6 +108,9 @@ static int is_objc_method_format (const 
8e71796
 static struct symtabs_and_lines decode_line_2 (struct symbol *[],
8e71796
 					       int, int, char ***);
8e71796
 
8e71796
+static struct symtabs_and_lines decode_line_3 (struct minimal_symbol *[],
8e71796
+					       int, int, char ***);
8e71796
+
8e71796
 static struct symtab *symtab_from_filename (char **argptr,
8e71796
 					    char *p, int is_quote_enclosed,
8e71796
 					    int *not_found_ptr);
eb9d945
@@ -194,13 +201,18 @@ total_number_of_methods (struct type *ty
8e71796
 /* Recursive helper function for decode_line_1.
8e71796
    Look for methods named NAME in type T.
8e71796
    Return number of matches.
8e71796
-   Put matches in SYM_ARR, which should have been allocated with
8e71796
+   Put symbol matches in SYM_ARR, which should have been allocated with
8e71796
    a size of total_number_of_methods (T) * sizeof (struct symbol *).
8e71796
+   In a special case where we are looking for constructors, we may
8e71796
+   have to return minimal symbols in the array: MSYM_ARR.  This occurs
8e71796
+   when the compiler does not generate mangled names for the constructor's
8e71796
+   debug info because there are multiple versions of the constructor
8e71796
+   (in-charge vs not-in-charge).
8e71796
    Note that this function is g++ specific.  */
8e71796
 
8e71796
 static int
eb9d945
 find_methods (struct type *t, char *name, enum language language,
eb9d945
-	      struct symbol **sym_arr)
eb9d945
+	      struct symbol **sym_arr, struct minimal_symbol **msym_arr)
8e71796
 {
8e71796
   int i1 = 0;
8e71796
   int ibase;
eb9d945
@@ -243,7 +255,7 @@ find_methods (struct type *t, char *name
8e71796
 	  if (strcmp_iw (name, method_name) == 0)
8e71796
 	    /* Find all the overloaded methods with that name.  */
eb9d945
 	    i1 += add_matching_methods (method_counter, t, language,
8e71796
-					sym_arr + i1);
eb9d945
+					sym_arr + i1, msym_arr);
8e71796
 	  else if (strncmp (class_name, name, name_len) == 0
8e71796
 		   && (class_name[name_len] == '\0'
8e71796
 		       || class_name[name_len] == '<'))
eb9d945
@@ -266,21 +278,100 @@ find_methods (struct type *t, char *name
8e71796
   if (i1 == 0)
8e71796
     for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
eb9d945
       i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
eb9d945
-			  language, sym_arr + i1);
eb9d945
+			  language, sym_arr + i1, msym_arr);
8e71796
 
8e71796
   return i1;
8e71796
 }
8e71796
 
8e71796
+static int
9231e41
+add_minsym_members (const char *class_name,
9231e41
+		    const char *member_name,
8e71796
+		    struct minimal_symbol **msym_arr)
8e71796
+{
8e71796
+  char *completion_name;
8e71796
+  char **list;
8e71796
+  int i;
8e71796
+  int comp_len;
8e71796
+  int counter = 0;
8e71796
+
8e71796
+  /* To find the member, we first cheat and use symbol completion.
8e71796
+     This will give us a list of all the member names including
8e71796
+     the function signature.  */
8e71796
+  completion_name = xmalloc (strlen (class_name) +
8e71796
+			     strlen (member_name) + 9);
8e71796
+  completion_name[0] = '\'';
8e71796
+  strcpy (completion_name+1, class_name);
8e71796
+  /* FIXME: make this the language class separator.  */
8e71796
+  strcat (completion_name, "::");
8e71796
+  strcat (completion_name, member_name);
8e71796
+  strcat (completion_name, "(");
8e71796
+  list = make_symbol_completion_list (completion_name,
8e71796
+				      completion_name+1);
8e71796
+
8e71796
+  /* Now that we have the list, we generate an array of their
8e71796
+     corresponding minimal symbols.  */
8e71796
+  counter = 0;
8e71796
+  while (list && list[counter] != NULL)
8e71796
+    {
8e71796
+      msym_arr[counter] = lookup_minimal_symbol (list[counter], NULL, NULL);
8e71796
+      ++counter;
8e71796
+    }
8e71796
+
8e71796
+  xfree (list);
8e71796
+
8e71796
+  /* In the case of constructors, there may be in-charge vs not-in-charge
8e71796
+     constructors.  Check for names with $base which indicates not-in-charge
8e71796
+     constructors.  */
8e71796
+  comp_len = strlen (completion_name);
8e71796
+  strcpy (completion_name + comp_len - 1, "$base(");
8e71796
+  list = make_symbol_completion_list (completion_name,
8e71796
+				      completion_name+1);
8e71796
+
8e71796
+  /* Again we have a list.  Add their minimal symbols to the array.  */
8e71796
+  i = 0;
8e71796
+  while (list && list[i] != NULL)
8e71796
+    {
8e71796
+      msym_arr[counter] = lookup_minimal_symbol (list[i++], NULL, NULL);
8e71796
+      ++counter;
8e71796
+    }
8e71796
+  xfree (list);
add1a2d
+
add1a2d
+  /* Target also the allocating/deleting variants.  */
add1a2d
+  if (member_name[0] == '~')
add1a2d
+    strcpy (completion_name + comp_len - 1, "$delete(");
add1a2d
+  else
add1a2d
+    strcpy (completion_name + comp_len - 1, "$allocate(");
add1a2d
+  list = make_symbol_completion_list (completion_name,
add1a2d
+				      completion_name+1);
add1a2d
+
add1a2d
+  /* Again we have a list.  Add their minimal symbols to the array.  */
add1a2d
+  i = 0;
add1a2d
+  while (list && list[i] != NULL)
add1a2d
+    {
add1a2d
+      msym_arr[counter] = lookup_minimal_symbol (list[i++], NULL, NULL);
add1a2d
+      ++counter;
add1a2d
+    }
add1a2d
+  xfree (list);
add1a2d
+
9231e41
+  xfree (completion_name);
8e71796
+
8e71796
+  return counter;
8e71796
+}
8e71796
+
8e71796
 /* Add the symbols associated to methods of the class whose type is T
8e71796
    and whose name matches the method indexed by METHOD_COUNTER in the
8e71796
    array SYM_ARR.  Return the number of methods added.  */
8e71796
 
8e71796
 static int
8e71796
 add_matching_methods (int method_counter, struct type *t,
eb9d945
-		      enum language language, struct symbol **sym_arr)
eb9d945
+		      enum language language, struct symbol **sym_arr,
8e71796
+		      struct minimal_symbol **msym_arr)
8e71796
 {
8e71796
   int field_counter;
8e71796
   int i1 = 0;
8e71796
+  int cons_index = 0;
8e71796
+  char *class_name = type_name_no_tag (t);
8e71796
+  char **list = NULL;
8e71796
 
8e71796
   for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
8e71796
        field_counter >= 0;
eb9d945
@@ -305,6 +396,16 @@ add_matching_methods (int method_counter
8e71796
       else
8e71796
 	phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
eb9d945
 
8e71796
+      /* Check for special case of looking for member that
8e71796
+	 doesn't have a mangled name provided.  This will happen
8e71796
+	 when we have in-charge and not-in-charge constructors.
8e71796
+	 Since we don't have a mangled name to work with, if we
8e71796
+	 look for the symbol, we can only find the class itself.
9231e41
+	 We can find the information we need in the minimal symbol
8e71796
+	 table which has the full member name information we need.  */
8e71796
+      if (strlen (phys_name) <= strlen (class_name))
8e71796
+	return add_minsym_members (class_name, phys_name, msym_arr);
eb9d945
+
8e71796
       /* Destructor is handled by caller, don't add it to
8e71796
 	 the list.  */
eb9d945
       if (is_destructor_name (phys_name) != 0)
eb9d945
@@ -330,6 +431,9 @@ add_matching_methods (int method_counter
8e71796
 	}
8e71796
     }
8e71796
 
8e71796
+  if (list)
8e71796
+    xfree (list);
8e71796
+
8e71796
   return i1;
8e71796
 }
8e71796
 
eb9d945
@@ -610,6 +714,146 @@ decode_line_2 (struct symbol *sym_arr[],
8e71796
   discard_cleanups (old_chain);
8e71796
   return return_values;
8e71796
 }
8e71796
+
8e71796
+/* Given a list of NELTS minimal symbols in MSYM_ARR, return a list of lines to
8e71796
+   operate on (ask user if necessary).
8e71796
+   If CANONICAL is non-NULL return a corresponding array of mangled names
8e71796
+   as canonical line specs there.  */
8e71796
+
8e71796
+static struct symtabs_and_lines
8e71796
+decode_line_3 (struct minimal_symbol *msym_arr[],
8e71796
+	       int nelts, int funfirstline,
8e71796
+	       char ***canonical)
8e71796
+{
8e71796
+  struct symtabs_and_lines values, return_values;
8e71796
+  char *args, *arg1;
8e71796
+  int i;
8e71796
+  char *prompt;
8e71796
+  char *symname;
8e71796
+  struct cleanup *old_chain;
8e71796
+  char **canonical_arr = (char **) NULL;
8e71796
+
8e71796
+  values.sals = (struct symtab_and_line *)
8e71796
+    alloca (nelts * sizeof (struct symtab_and_line));
8e71796
+  return_values.sals = (struct symtab_and_line *)
8e71796
+    xmalloc (nelts * sizeof (struct symtab_and_line));
8e71796
+  old_chain = make_cleanup (xfree, return_values.sals);
8e71796
+
8e71796
+  if (canonical)
8e71796
+    {
8e71796
+      canonical_arr = (char **) xmalloc (nelts * sizeof (char *));
8e71796
+      make_cleanup (xfree, canonical_arr);
8e71796
+      memset (canonical_arr, 0, nelts * sizeof (char *));
8e71796
+      *canonical = canonical_arr;
8e71796
+    }
8e71796
+
8e71796
+  i = 0;
8e71796
+  printf_unfiltered ("[0] cancel\n[1] all\n");
8e71796
+  while (i < nelts)
8e71796
+    {
8e71796
+      init_sal (&return_values.sals[i]);	/* Initialize to zeroes.  */
8e71796
+      init_sal (&values.sals[i]);
8e71796
+      if (msym_arr[i])
8e71796
+	{
9231e41
+	  struct symtabs_and_lines msal = minsym_found (funfirstline,
8e71796
+						        msym_arr[i]);
9231e41
+	  memcpy (&values.sals[i], &msal.sals[0],
8e71796
+		  sizeof (struct symtab_and_line));
8e71796
+	  if (values.sals[i].symtab)
8e71796
+	    printf_unfiltered ("[%d] %s at %s:%d\n",
8e71796
+			       (i + 2),
8e71796
+			       SYMBOL_PRINT_NAME (msym_arr[i]),
8e71796
+			       values.sals[i].symtab->filename,
8e71796
+			       values.sals[i].line);
8e71796
+	  else
8e71796
+	    printf_unfiltered ("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n",
8e71796
+			       (i + 2),
8e71796
+			       SYMBOL_PRINT_NAME (msym_arr[i]),
8e71796
+			       values.sals[i].line);
8e71796
+
8e71796
+	}
8e71796
+      else
8e71796
+	printf_unfiltered ("?HERE\n");
8e71796
+      i++;
8e71796
+    }
8e71796
+
8e71796
+  prompt = getenv ("PS2");
8e71796
+  if (prompt == NULL)
8e71796
+    {
8e71796
+      prompt = "> ";
8e71796
+    }
8e71796
+  args = command_line_input (prompt, 0, "overload-choice");
8e71796
+
8e71796
+  if (args == 0 || *args == 0)
8e71796
+    error_no_arg ("one or more choice numbers");
8e71796
+
8e71796
+  i = 0;
8e71796
+  while (*args)
8e71796
+    {
8e71796
+      int num;
8e71796
+
8e71796
+      arg1 = args;
8e71796
+      while (*arg1 >= '0' && *arg1 <= '9')
8e71796
+	arg1++;
8e71796
+      if (*arg1 && *arg1 != ' ' && *arg1 != '\t')
8e71796
+	error ("Arguments must be choice numbers.");
8e71796
+
8e71796
+      num = atoi (args);
8e71796
+
8e71796
+      if (num == 0)
8e71796
+	error ("canceled");
8e71796
+      else if (num == 1)
8e71796
+	{
8e71796
+	  if (canonical_arr)
8e71796
+	    {
8e71796
+	      for (i = 0; i < nelts; i++)
8e71796
+		{
8e71796
+		  if (canonical_arr[i] == NULL)
8e71796
+		    {
8e71796
+		      symname = DEPRECATED_SYMBOL_NAME (msym_arr[i]);
8e71796
+		      canonical_arr[i] = savestring (symname, strlen (symname));
8e71796
+		    }
8e71796
+		}
8e71796
+	    }
8e71796
+	  memcpy (return_values.sals, values.sals,
8e71796
+		  (nelts * sizeof (struct symtab_and_line)));
8e71796
+	  return_values.nelts = nelts;
8e71796
+	  discard_cleanups (old_chain);
8e71796
+	  return return_values;
8e71796
+	}
8e71796
+
8e71796
+      if (num >= nelts + 2)
8e71796
+	{
8e71796
+	  printf_unfiltered ("No choice number %d.\n", num);
8e71796
+	}
8e71796
+      else
8e71796
+	{
8e71796
+	  num -= 2;
8e71796
+	  if (values.sals[num].pc)
8e71796
+	    {
8e71796
+	      if (canonical_arr)
8e71796
+		{
8e71796
+		  symname = DEPRECATED_SYMBOL_NAME (msym_arr[num]);
8e71796
+		  make_cleanup (xfree, symname);
8e71796
+		  canonical_arr[i] = savestring (symname, strlen (symname));
8e71796
+		}
8e71796
+	      return_values.sals[i++] = values.sals[num];
8e71796
+	      values.sals[num].pc = 0;
8e71796
+	    }
8e71796
+	  else
8e71796
+	    {
8e71796
+	      printf_unfiltered ("duplicate request for %d ignored.\n", num);
8e71796
+	    }
8e71796
+	}
8e71796
+
8e71796
+      args = arg1;
8e71796
+      while (*args == ' ' || *args == '\t')
8e71796
+	args++;
8e71796
+    }
8e71796
+  return_values.nelts = i;
8e71796
+  discard_cleanups (old_chain);
8e71796
+  return return_values;
8e71796
+}
8e71796
 
8e71796
 /* The parser of linespec itself. */
8e71796
 
eb9d945
@@ -1414,35 +1658,46 @@ find_method (int funfirstline, char ***c
8e71796
   struct symbol **sym_arr =  alloca (total_number_of_methods (t)
8e71796
 				     * sizeof (struct symbol *));
eb9d945
 
8e71796
+  struct minimal_symbol **msym_arr =  alloca (total_number_of_methods (t)
8e71796
+				     * sizeof (struct minimal_symbol *));
8e71796
+
8e71796
+  msym_arr[0] = NULL;
eb9d945
+
8e71796
   /* Find all methods with a matching name, and put them in
8e71796
      sym_arr.  */
8e71796
 
eb9d945
-  i1 = collect_methods (copy, t, sym_class, sym_arr);
eb9d945
+  i1 = collect_methods (copy, t, sym_class, sym_arr, msym_arr);
8e71796
 
8e71796
   if (i1 == 1)
8e71796
     {
8e71796
       /* There is exactly one field with that name.  */
8e71796
-      sym = sym_arr[0];
8e71796
-
8e71796
-      if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
8e71796
-	{
8e71796
-	  values.sals = (struct symtab_and_line *)
8e71796
-	    xmalloc (sizeof (struct symtab_and_line));
8e71796
-	  values.nelts = 1;
8e71796
-	  values.sals[0] = find_function_start_sal (sym,
8e71796
-						    funfirstline);
8e71796
-	}
8e71796
+      if (msym_arr[0] != NULL)
8e71796
+	return minsym_found (funfirstline, msym_arr[0]);
8e71796
       else
8e71796
 	{
9231e41
-	  values.sals = NULL;
8e71796
-	  values.nelts = 0;
8e71796
+          sym = sym_arr[0];
8e71796
+
8e71796
+          if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
8e71796
+	    {
8e71796
+	      values.sals = (struct symtab_and_line *)
8e71796
+	        xmalloc (sizeof (struct symtab_and_line));
8e71796
+	      values.nelts = 1;
8e71796
+	      values.sals[0] = find_function_start_sal (sym,
8e71796
+						        funfirstline);
8e71796
+   	    }
8e71796
+          else
8e71796
+	    {
8e71796
+	      values.nelts = 0;
8e71796
+	    }
8e71796
+          return values;
8e71796
 	}
8e71796
-      return values;
8e71796
     }
8e71796
   if (i1 > 0)
8e71796
     {
8e71796
       /* There is more than one field with that name
8e71796
 	 (overloaded).  Ask the user which one to use.  */
8e71796
+      if (msym_arr[0] != NULL)
eb9d945
+	return decode_line_3 (msym_arr, i1, funfirstline, canonical);
8e71796
       return decode_line_2 (sym_arr, i1, funfirstline, canonical);
8e71796
     }
8e71796
   else
eb9d945
@@ -1469,11 +1722,12 @@ find_method (int funfirstline, char ***c
8e71796
 }
8e71796
 
8e71796
 /* Find all methods named COPY in the class whose type is T, and put
8e71796
-   them in SYM_ARR.  Return the number of methods found.  */
8e71796
+   them in SYM_ARR or MSYM_ARR.  Return the number of methods found.  */
8e71796
 
8e71796
 static int
8e71796
 collect_methods (char *copy, struct type *t,
eb9d945
-		 struct symbol *sym_class, struct symbol **sym_arr)
eb9d945
+		 struct symbol *sym_class, struct symbol **sym_arr,
8e71796
+		 struct minimal_symbol **msym_arr)
8e71796
 {
8e71796
   int i1 = 0;	/*  Counter for the symbol array.  */
8e71796
 
eb9d945
@@ -1495,7 +1749,7 @@ collect_methods (char *copy, struct type
8e71796
 	}
8e71796
     }
8e71796
   else
eb9d945
-    i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr);
eb9d945
+    i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr, msym_arr);
8e71796
 
8e71796
   return i1;
8e71796
 }
eb9d945
@@ -1717,12 +1971,13 @@ decode_dollar (char *copy, int funfirstl
cafa2ff
    and do not issue an error message.  */ 
cafa2ff
 
cafa2ff
 static struct symtabs_and_lines
cafa2ff
-decode_variable (char *copy, int funfirstline, char ***canonical,
cafa2ff
-		 struct symtab *file_symtab, int *not_found_ptr)
cafa2ff
+decode_variable_1 (char *copy, int funfirstline, char ***canonical,
cafa2ff
+		   struct symtab *file_symtab)
cafa2ff
 {
cafa2ff
   struct symbol *sym;
cafa2ff
   /* The symtab that SYM was found in.  */
cafa2ff
   struct symtab *sym_symtab;
cafa2ff
+  struct symtabs_and_lines retval;
cafa2ff
 
cafa2ff
   struct minimal_symbol *msymbol;
cafa2ff
 
eb9d945
@@ -1740,8 +1995,25 @@ decode_variable (char *copy, int funfirs
cafa2ff
   msymbol = lookup_minimal_symbol (copy, NULL, NULL);
cafa2ff
 
cafa2ff
   if (msymbol != NULL)
cafa2ff
-    return minsym_found (funfirstline, msymbol);
cafa2ff
+    {
cafa2ff
+      retval = minsym_found (funfirstline, msymbol);
cafa2ff
+
cafa2ff
+      /* Create a `filename:linkage_symbol_name' reference.  */
cafa2ff
+      if (file_symtab == 0)
cafa2ff
+	build_canonical_line_spec (retval.sals, SYMBOL_LINKAGE_NAME (msymbol),
cafa2ff
+				   canonical);
eb9d945
 
cafa2ff
+      return retval;
cafa2ff
+    }
eb9d945
+
cafa2ff
+  retval.nelts = 0;
cafa2ff
+  retval.sals = NULL;
cafa2ff
+  return retval;
cafa2ff
+}
cafa2ff
+
cafa2ff
+static void
cafa2ff
+decode_variable_not_found (char *copy, int *not_found_ptr)
cafa2ff
+{
cafa2ff
   if (!have_full_symbols () &&
cafa2ff
       !have_partial_symbols () && !have_minimal_symbols ())
cafa2ff
     error (_("No symbol table is loaded.  Use the \"file\" command."));
eb9d945
@@ -1751,6 +2023,132 @@ decode_variable (char *copy, int funfirs
cafa2ff
   throw_error (NOT_FOUND_ERROR, _("Function \"%s\" not defined."), copy);
cafa2ff
 }
cafa2ff
 
cafa2ff
+/* Wrapper of DECODE_VARIABLE_1 collecting the results for all the found
cafa2ff
+   VARIANTS of the symbol COPY.  */
cafa2ff
+
cafa2ff
+static struct symtabs_and_lines
cafa2ff
+decode_variable (char *copy, int funfirstline, char ***canonical,
cafa2ff
+		 struct symtab *file_symtab, int *not_found_ptr)
cafa2ff
+{
cafa2ff
+  char *src;
cafa2ff
+  char *src_point;
cafa2ff
+  char *s, *point;
cafa2ff
+  /* Keep "" last as the trimming part always matches it.  */
cafa2ff
+  const char *variants[] = {"$base","$allocate","$delete",""};
cafa2ff
+  int i;
cafa2ff
+  char *dst, *dst_point;
cafa2ff
+  struct
cafa2ff
+    {
cafa2ff
+      struct symtabs_and_lines sals;
cafa2ff
+      char **canonical;
cafa2ff
+    } found[ARRAY_SIZE (variants)];
cafa2ff
+  struct symtabs_and_lines retval_sals;
cafa2ff
+  char **retval_canonical = NULL;	/* Shut up GCC.  */
cafa2ff
+  int filled;
cafa2ff
+  int canonicals = 0;	/* Shut up GCC.  */
cafa2ff
+
cafa2ff
+  src = copy;
cafa2ff
+  src_point = strchr (src, '(');
cafa2ff
+  if (src_point == NULL)
cafa2ff
+    {
cafa2ff
+      struct symtabs_and_lines sals;
cafa2ff
+
cafa2ff
+      sals = decode_variable_1 (src, funfirstline, canonical, file_symtab);
cafa2ff
+      if (sals.nelts > 0)
cafa2ff
+        return sals;
cafa2ff
+      decode_variable_not_found (copy, not_found_ptr);
cafa2ff
+      /* NOTREACHED */
cafa2ff
+    }
cafa2ff
+
cafa2ff
+  dst = xmalloc (strlen (src) + strlen ("$allocate") + 1);
cafa2ff
+  dst_point = dst + (src_point - src);
cafa2ff
+
cafa2ff
+  memcpy (dst, src, src_point - src);
cafa2ff
+
cafa2ff
+  /* Trim out any variant markers there first.  */
cafa2ff
+  for (i = 0; i < ARRAY_SIZE (variants); i++)
cafa2ff
+    {
cafa2ff
+      size_t len = strlen (variants[i]);
cafa2ff
+
cafa2ff
+      if (dst_point - dst >= len
cafa2ff
+	  && memcmp (dst_point - len, variants[i], len) == 0)
cafa2ff
+	{
cafa2ff
+	  dst_point -= len;
cafa2ff
+	  /* In fact it should not be needed here.  */
cafa2ff
+	  break;
cafa2ff
+	}
cafa2ff
+    }
cafa2ff
+
cafa2ff
+  filled = 0;
cafa2ff
+  /* And now try to append all of them.  */
cafa2ff
+  for (i = 0; i < ARRAY_SIZE (variants); i++)
cafa2ff
+    {
cafa2ff
+      size_t len = strlen (variants[i]);
cafa2ff
+      struct minimal_symbol *minsym2;
cafa2ff
+
cafa2ff
+      memcpy (dst_point, variants[i], len);
cafa2ff
+      strcpy (dst_point + len, src_point);
cafa2ff
+
cafa2ff
+      found[i].canonical = NULL;
cafa2ff
+      found[i].sals = decode_variable_1 (dst, funfirstline,
cafa2ff
+					 (canonical == NULL ? NULL
cafa2ff
+							 : &found[i].canonical),
cafa2ff
+					 file_symtab);
cafa2ff
+      filled += found[i].sals.nelts;
cafa2ff
+    }
cafa2ff
+  xfree (dst);
cafa2ff
+  if (filled == 0)
cafa2ff
+    {
cafa2ff
+      decode_variable_not_found (copy, not_found_ptr);
cafa2ff
+      /* NOTREACHED */
cafa2ff
+    }
cafa2ff
+
cafa2ff
+  retval_sals.nelts = filled;
cafa2ff
+  retval_sals.sals = xmalloc (filled * sizeof *retval_sals.sals);
cafa2ff
+  if (canonical != NULL)
cafa2ff
+    {
cafa2ff
+      retval_canonical = xmalloc (filled * sizeof *retval_canonical);
cafa2ff
+      canonicals = 0;
cafa2ff
+    }
cafa2ff
+  filled = 0;
cafa2ff
+  for (i = 0; i < ARRAY_SIZE (variants); i++)
cafa2ff
+    {
cafa2ff
+      memcpy (&retval_sals.sals[filled], found[i].sals.sals,
cafa2ff
+              found[i].sals.nelts * sizeof *retval_sals.sals);
cafa2ff
+      xfree (found[i].sals.sals);
cafa2ff
+      if (canonical != NULL)
cafa2ff
+        {
cafa2ff
+          if (found[i].canonical == NULL)
cafa2ff
+	    memset (&retval_canonical[filled], 0,
cafa2ff
+	            found[i].sals.nelts * sizeof *retval_canonical);
cafa2ff
+	  else
cafa2ff
+	    {
cafa2ff
+	      int j;
cafa2ff
+
cafa2ff
+	      memcpy (&retval_canonical[filled], found[i].canonical,
cafa2ff
+		      found[i].sals.nelts * sizeof *retval_canonical);
cafa2ff
+	      for (j = 0; j < found[i].sals.nelts; j++)
cafa2ff
+	        if (found[i].canonical[j] != NULL)
cafa2ff
+		  canonicals++;
cafa2ff
+	      xfree (found[i].canonical);
cafa2ff
+	    }
cafa2ff
+	}
cafa2ff
+      filled += found[i].sals.nelts;
cafa2ff
+    }
cafa2ff
+  gdb_assert (filled == retval_sals.nelts);
cafa2ff
+
cafa2ff
+  if (canonical != NULL)
cafa2ff
+    {
cafa2ff
+      if (canonicals != 0)
cafa2ff
+	*canonical = retval_canonical;
cafa2ff
+      else
cafa2ff
+	{
cafa2ff
+	  *canonical = NULL;
cafa2ff
+	  xfree (retval_canonical);
cafa2ff
+	}
cafa2ff
+    }
cafa2ff
+  return retval_sals;
cafa2ff
+}
cafa2ff
 
cafa2ff
 
cafa2ff
 
eb9d945
Index: gdb-6.7/gdb/Makefile.in
eb9d945
===================================================================
eb9d945
--- gdb-6.7.orig/gdb/Makefile.in	2007-10-13 05:09:50.000000000 +0200
eb9d945
+++ gdb-6.7/gdb/Makefile.in	2007-10-13 05:15:13.000000000 +0200
eb9d945
@@ -2233,7 +2233,8 @@ libunwind-frame.o: libunwind-frame.c $(d
cafa2ff
 linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
cafa2ff
 	$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
cafa2ff
 	$(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) \
eb9d945
-	$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h)
eb9d945
+	$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h) \
eb9d945
+	$(gdb_assert_h)
cafa2ff
 linux-fork.o: linux-fork.c $(defs_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) \
cafa2ff
 	$(infcall_h) $(gdb_assert_h) $(gdb_string_h) $(linux_fork_h) \
cafa2ff
 	$(linux_nat_h)