9231e41
Index: gdb-6.5/gdb/linespec.c
9231e41
===================================================================
9231e41
--- gdb-6.5.orig/gdb/linespec.c	2006-01-10 20:14:43.000000000 -0200
9231e41
+++ gdb-6.5/gdb/linespec.c	2006-07-07 01:04:56.000000000 -0300
9231e41
@@ -75,7 +75,8 @@ static struct symtabs_and_lines find_met
8e71796
 					     struct symbol *sym_class);
8e71796
 
8e71796
 static int collect_methods (char *copy, struct type *t,
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, ...)
9231e41
@@ -83,10 +84,12 @@ static NORETURN void cplusplus_error (co
8e71796
 
8e71796
 static int total_number_of_methods (struct type *type);
8e71796
 
8e71796
-static int find_methods (struct type *, char *, struct symbol **);
8e71796
+static int find_methods (struct type *, char *, struct symbol **,
8e71796
+			 struct minimal_symbol **);
8e71796
 
8e71796
 static int add_matching_methods (int method_counter, struct type *t,
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,
8e71796
 			     struct symbol **sym_arr);
9231e41
@@ -101,6 +104,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);
9231e41
@@ -191,12 +197,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
8e71796
-find_methods (struct type *t, char *name, struct symbol **sym_arr)
8e71796
+find_methods (struct type *t, char *name, struct symbol **sym_arr,
8e71796
+	      struct minimal_symbol **msym_arr)
8e71796
 {
8e71796
   int i1 = 0;
8e71796
   int ibase;
9231e41
@@ -239,7 +251,8 @@ find_methods (struct type *t, char *name
8e71796
 	  if (strcmp_iw (name, method_name) == 0)
8e71796
 	    /* Find all the overloaded methods with that name.  */
8e71796
 	    i1 += add_matching_methods (method_counter, t,
8e71796
-					sym_arr + i1);
8e71796
+					sym_arr + i1,
8e71796
+					msym_arr);
8e71796
 	  else if (strncmp (class_name, name, name_len) == 0
8e71796
 		   && (class_name[name_len] == '\0'
8e71796
 		       || class_name[name_len] == '<'))
9231e41
@@ -261,21 +274,83 @@ find_methods (struct type *t, char *name
8e71796
 
8e71796
   if (i1 == 0)
8e71796
     for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
8e71796
-      i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
8e71796
+      i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1,
8e71796
+			  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);
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,
8e71796
-		      struct symbol **sym_arr)
8e71796
+		      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;
9231e41
@@ -299,6 +374,16 @@ add_matching_methods (int method_counter
8e71796
 	}
8e71796
       else
8e71796
 	phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
8e71796
+
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);
8e71796
 		
8e71796
       /* Destructor is handled by caller, don't add it to
8e71796
 	 the list.  */
9231e41
@@ -324,6 +409,9 @@ add_matching_methods (int method_counter
8e71796
 	}
8e71796
     }
8e71796
 
8e71796
+  if (list)
8e71796
+    xfree (list);
8e71796
+
8e71796
   return i1;
8e71796
 }
8e71796
 
9231e41
@@ -603,6 +691,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
 
9231e41
@@ -1406,36 +1634,46 @@ find_method (int funfirstline, char ***c
8e71796
   int i1;	/*  Counter for the symbol array.  */
8e71796
   struct symbol **sym_arr =  alloca (total_number_of_methods (t)
8e71796
 				     * sizeof (struct symbol *));
8e71796
+  struct minimal_symbol **msym_arr =  alloca (total_number_of_methods (t)
8e71796
+				     * sizeof (struct minimal_symbol *));
8e71796
+
8e71796
+  msym_arr[0] = NULL;
8e71796
 
8e71796
   /* Find all methods with a matching name, and put them in
8e71796
      sym_arr.  */
8e71796
 
8e71796
-  i1 = collect_methods (copy, t, sym_arr);
8e71796
+  i1 = collect_methods (copy, t, 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)
8e71796
+        return decode_line_3 (msym_arr, i1, funfirstline, canonical);
8e71796
       return decode_line_2 (sym_arr, i1, funfirstline, canonical);
8e71796
     }
8e71796
   else
9231e41
@@ -1462,11 +1700,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,
8e71796
-		 struct symbol **sym_arr)
8e71796
+		 struct symbol **sym_arr,
8e71796
+		 struct minimal_symbol **msym_arr)
8e71796
 {
8e71796
   int i1 = 0;	/*  Counter for the symbol array.  */
8e71796
 
9231e41
@@ -1488,7 +1727,7 @@ collect_methods (char *copy, struct type
8e71796
 	}
8e71796
     }
8e71796
   else
8e71796
-    i1 = find_methods (t, copy, sym_arr);
8e71796
+    i1 = find_methods (t, copy, sym_arr, msym_arr);
8e71796
 
8e71796
   return i1;
8e71796
 }