gdb/gdb-6.3-linespec-20041213.patch

413 lines
12 KiB
Diff
Raw Normal View History

--- gdb-6.3/gdb/linespec.c.fix Mon Dec 13 19:55:27 2004
+++ gdb-6.3/gdb/linespec.c Mon Dec 13 19:59:05 2004
@@ -73,7 +73,8 @@ static struct symtabs_and_lines find_met
struct symbol *sym_class);
static int collect_methods (char *copy, struct type *t,
- struct symbol **sym_arr);
+ struct symbol **sym_arr,
+ struct minimal_symbol **msym_arr);
static NORETURN void cplusplus_error (const char *name,
const char *fmt, ...)
@@ -81,10 +82,12 @@ static NORETURN void cplusplus_error (co
static int total_number_of_methods (struct type *type);
-static int find_methods (struct type *, char *, struct symbol **);
+static int find_methods (struct type *, char *, struct symbol **,
+ struct minimal_symbol **);
static int add_matching_methods (int method_counter, struct type *t,
- struct symbol **sym_arr);
+ struct symbol **sym_arr,
+ struct minimal_symbol **msym_arr);
static int add_constructors (int method_counter, struct type *t,
struct symbol **sym_arr);
@@ -99,6 +102,9 @@ static int is_objc_method_format (const
static struct symtabs_and_lines decode_line_2 (struct symbol *[],
int, int, char ***);
+static struct symtabs_and_lines decode_line_3 (struct minimal_symbol *[],
+ int, int, char ***);
+
static struct symtab *symtab_from_filename (char **argptr,
char *p, int is_quote_enclosed,
int *not_found_ptr);
@@ -189,12 +195,18 @@ total_number_of_methods (struct type *ty
/* 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
+ Put symbol matches in SYM_ARR, which should have been allocated with
a size of total_number_of_methods (T) * sizeof (struct symbol *).
+ In a special case where we are looking for constructors, we may
+ have to return minimal symbols in the array: MSYM_ARR. This occurs
+ when the compiler does not generate mangled names for the constructor's
+ debug info because there are multiple versions of the constructor
+ (in-charge vs not-in-charge).
Note that this function is g++ specific. */
static int
-find_methods (struct type *t, char *name, struct symbol **sym_arr)
+find_methods (struct type *t, char *name, struct symbol **sym_arr,
+ struct minimal_symbol **msym_arr)
{
int i1 = 0;
int ibase;
@@ -237,7 +249,8 @@ find_methods (struct type *t, char *name
if (strcmp_iw (name, method_name) == 0)
/* Find all the overloaded methods with that name. */
i1 += add_matching_methods (method_counter, t,
- sym_arr + i1);
+ sym_arr + i1,
+ msym_arr);
else if (strncmp (class_name, name, name_len) == 0
&& (class_name[name_len] == '\0'
|| class_name[name_len] == '<'))
@@ -259,21 +272,83 @@ find_methods (struct type *t, char *name
if (i1 == 0)
for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
- i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1);
+ i1 += find_methods (TYPE_BASECLASS (t, ibase), name, sym_arr + i1,
+ msym_arr);
return i1;
}
+static int
+add_minsym_members (const char *class_name,
+ const char *member_name,
+ struct minimal_symbol **msym_arr)
+{
+ char *completion_name;
+ char **list;
+ int i;
+ int comp_len;
+ int counter = 0;
+
+ /* To find the member, we first cheat and use symbol completion.
+ This will give us a list of all the member names including
+ the function signature. */
+ completion_name = xmalloc (strlen (class_name) +
+ strlen (member_name) + 9);
+ completion_name[0] = '\'';
+ strcpy (completion_name+1, class_name);
+ /* FIXME: make this the language class separator. */
+ strcat (completion_name, "::");
+ strcat (completion_name, member_name);
+ strcat (completion_name, "(");
+ list = make_symbol_completion_list (completion_name,
+ completion_name+1);
+
+ /* Now that we have the list, we generate an array of their
+ corresponding minimal symbols. */
+ counter = 0;
+ while (list && list[counter] != NULL)
+ {
+ msym_arr[counter] = lookup_minimal_symbol (list[counter], NULL, NULL);
+ ++counter;
+ }
+
+ xfree (list);
+
+ /* In the case of constructors, there may be in-charge vs not-in-charge
+ constructors. Check for names with $base which indicates not-in-charge
+ constructors. */
+ comp_len = strlen (completion_name);
+ strcpy (completion_name + comp_len - 1, "$base(");
+ list = make_symbol_completion_list (completion_name,
+ completion_name+1);
+
+ /* Again we have a list. Add their minimal symbols to the array. */
+ i = 0;
+ while (list && list[i] != NULL)
+ {
+ msym_arr[counter] = lookup_minimal_symbol (list[i++], NULL, NULL);
+ ++counter;
+ }
+ xfree (list);
+ xfree (completion_name);
+
+ return counter;
+}
+
/* 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,
- struct symbol **sym_arr)
+ struct symbol **sym_arr,
+ struct minimal_symbol **msym_arr)
{
int field_counter;
int i1 = 0;
+ int cons_index = 0;
+ char *class_name = type_name_no_tag (t);
+ char **list = NULL;
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
field_counter >= 0;
@@ -297,6 +372,16 @@ add_matching_methods (int method_counter
}
else
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
+
+ /* Check for special case of looking for member that
+ doesn't have a mangled name provided. This will happen
+ when we have in-charge and not-in-charge constructors.
+ Since we don't have a mangled name to work with, if we
+ look for the symbol, we can only find the class itself.
+ We can find the information we need in the minimal symbol
+ table which has the full member name information we need. */
+ if (strlen (phys_name) <= strlen (class_name))
+ return add_minsym_members (class_name, phys_name, msym_arr);
/* Destructor is handled by caller, don't add it to
the list. */
@@ -322,6 +407,9 @@ add_matching_methods (int method_counter
}
}
+ if (list)
+ xfree (list);
+
return i1;
}
@@ -601,6 +689,146 @@ decode_line_2 (struct symbol *sym_arr[],
discard_cleanups (old_chain);
return return_values;
}
+
+/* Given a list of NELTS minimal symbols in MSYM_ARR, return a list of lines to
+ operate on (ask user if necessary).
+ If CANONICAL is non-NULL return a corresponding array of mangled names
+ as canonical line specs there. */
+
+static struct symtabs_and_lines
+decode_line_3 (struct minimal_symbol *msym_arr[],
+ int nelts, int funfirstline,
+ char ***canonical)
+{
+ struct symtabs_and_lines values, return_values;
+ char *args, *arg1;
+ int i;
+ char *prompt;
+ char *symname;
+ struct cleanup *old_chain;
+ char **canonical_arr = (char **) NULL;
+
+ values.sals = (struct symtab_and_line *)
+ alloca (nelts * sizeof (struct symtab_and_line));
+ return_values.sals = (struct symtab_and_line *)
+ xmalloc (nelts * sizeof (struct symtab_and_line));
+ old_chain = make_cleanup (xfree, return_values.sals);
+
+ if (canonical)
+ {
+ canonical_arr = (char **) xmalloc (nelts * sizeof (char *));
+ make_cleanup (xfree, canonical_arr);
+ memset (canonical_arr, 0, nelts * sizeof (char *));
+ *canonical = canonical_arr;
+ }
+
+ i = 0;
+ printf_unfiltered ("[0] cancel\n[1] all\n");
+ while (i < nelts)
+ {
+ init_sal (&return_values.sals[i]); /* Initialize to zeroes. */
+ init_sal (&values.sals[i]);
+ if (msym_arr[i])
+ {
+ struct symtabs_and_lines msal = minsym_found (funfirstline,
+ msym_arr[i]);
+ memcpy (&values.sals[i], &msal.sals[0],
+ sizeof (struct symtab_and_line));
+ if (values.sals[i].symtab)
+ printf_unfiltered ("[%d] %s at %s:%d\n",
+ (i + 2),
+ SYMBOL_PRINT_NAME (msym_arr[i]),
+ values.sals[i].symtab->filename,
+ values.sals[i].line);
+ else
+ printf_unfiltered ("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n",
+ (i + 2),
+ SYMBOL_PRINT_NAME (msym_arr[i]),
+ values.sals[i].line);
+
+ }
+ else
+ printf_unfiltered ("?HERE\n");
+ i++;
+ }
+
+ prompt = getenv ("PS2");
+ if (prompt == NULL)
+ {
+ prompt = "> ";
+ }
+ args = command_line_input (prompt, 0, "overload-choice");
+
+ if (args == 0 || *args == 0)
+ error_no_arg ("one or more choice numbers");
+
+ i = 0;
+ while (*args)
+ {
+ int num;
+
+ arg1 = args;
+ while (*arg1 >= '0' && *arg1 <= '9')
+ arg1++;
+ if (*arg1 && *arg1 != ' ' && *arg1 != '\t')
+ error ("Arguments must be choice numbers.");
+
+ num = atoi (args);
+
+ if (num == 0)
+ error ("canceled");
+ else if (num == 1)
+ {
+ if (canonical_arr)
+ {
+ for (i = 0; i < nelts; i++)
+ {
+ if (canonical_arr[i] == NULL)
+ {
+ symname = DEPRECATED_SYMBOL_NAME (msym_arr[i]);
+ canonical_arr[i] = savestring (symname, strlen (symname));
+ }
+ }
+ }
+ memcpy (return_values.sals, values.sals,
+ (nelts * sizeof (struct symtab_and_line)));
+ return_values.nelts = nelts;
+ discard_cleanups (old_chain);
+ return return_values;
+ }
+
+ if (num >= nelts + 2)
+ {
+ printf_unfiltered ("No choice number %d.\n", num);
+ }
+ else
+ {
+ num -= 2;
+ if (values.sals[num].pc)
+ {
+ if (canonical_arr)
+ {
+ symname = DEPRECATED_SYMBOL_NAME (msym_arr[num]);
+ make_cleanup (xfree, symname);
+ canonical_arr[i] = savestring (symname, strlen (symname));
+ }
+ return_values.sals[i++] = values.sals[num];
+ values.sals[num].pc = 0;
+ }
+ else
+ {
+ printf_unfiltered ("duplicate request for %d ignored.\n", num);
+ }
+ }
+
+ args = arg1;
+ while (*args == ' ' || *args == '\t')
+ args++;
+ }
+ return_values.nelts = i;
+ discard_cleanups (old_chain);
+ return return_values;
+}
/* The parser of linespec itself. */
@@ -1404,35 +1632,46 @@ find_method (int funfirstline, char ***c
int i1; /* Counter for the symbol array. */
struct symbol **sym_arr = alloca (total_number_of_methods (t)
* sizeof (struct symbol *));
+ struct minimal_symbol **msym_arr = alloca (total_number_of_methods (t)
+ * sizeof (struct minimal_symbol *));
+
+ msym_arr[0] = NULL;
/* Find all methods with a matching name, and put them in
sym_arr. */
- i1 = collect_methods (copy, t, sym_arr);
+ i1 = collect_methods (copy, t, sym_arr, msym_arr);
if (i1 == 1)
{
/* There is exactly one field with that name. */
- sym = sym_arr[0];
-
- if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
- {
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.nelts = 1;
- values.sals[0] = find_function_start_sal (sym,
- funfirstline);
- }
+ if (msym_arr[0] != NULL)
+ return minsym_found (funfirstline, msym_arr[0]);
else
{
- values.nelts = 0;
+ sym = sym_arr[0];
+
+ if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
+ values.nelts = 1;
+ values.sals[0] = find_function_start_sal (sym,
+ funfirstline);
+ }
+ else
+ {
+ values.nelts = 0;
+ }
+ return values;
}
- return values;
}
if (i1 > 0)
{
/* There is more than one field with that name
(overloaded). Ask the user which one to use. */
+ if (msym_arr[0] != NULL)
+ return decode_line_3 (msym_arr, i1, funfirstline, canonical);
return decode_line_2 (sym_arr, i1, funfirstline, canonical);
}
else
@@ -1459,11 +1698,12 @@ find_method (int funfirstline, char ***c
}
/* Find all methods named COPY in the class whose type is T, and put
- them in SYM_ARR. Return the number of methods found. */
+ them in SYM_ARR or MSYM_ARR. Return the number of methods found. */
static int
collect_methods (char *copy, struct type *t,
- struct symbol **sym_arr)
+ struct symbol **sym_arr,
+ struct minimal_symbol **msym_arr)
{
int i1 = 0; /* Counter for the symbol array. */
@@ -1485,7 +1725,7 @@ collect_methods (char *copy, struct type
}
}
else
- i1 = find_methods (t, copy, sym_arr);
+ i1 = find_methods (t, copy, sym_arr, msym_arr);
return i1;
}