]>
Commit | Line | Data |
---|---|---|
3a58abaf AM |
1 | [base] |
2 | ||
3 | 2007-09-21 Jan Kratochvil <jan.kratochvil@redhat.com> | |
4 | ||
5 | * linespec.c (add_minsym_members): Support also the `$allocate' and | |
6 | `$delete' variants. | |
7 | ||
8 | 2007-10-05 Jan Kratochvil <jan.kratochvil@redhat.com> | |
9 | ||
10 | * linespec.c (add_minsym_members): Support also the `$allocate' and | |
11 | `$delete' variants. | |
12 | (decode_variable): Renamed to ... | |
13 | (decode_variable_1) ... here, its parameter NOT_FOUND_PTR and its | |
14 | exception throwing was moved to ... | |
15 | (decode_variable_not_found): ... a new function here. | |
16 | (decode_variable): New function. | |
17 | ||
18 | 2007-10-31 Jan Kratochvil <jan.kratochvil@redhat.com> | |
19 | ||
20 | Port to GDB-6.7. | |
21 | ||
22 | [ Remove decode_variable* for GDB-6.8+ as no longer needed. ] | |
23 | ||
24 | Index: gdb-6.8.50.20081128/gdb/linespec.c | |
25 | =================================================================== | |
26 | --- gdb-6.8.50.20081128.orig/gdb/linespec.c 2008-09-05 13:37:17.000000000 +0200 | |
27 | +++ gdb-6.8.50.20081128/gdb/linespec.c 2008-12-04 01:43:36.000000000 +0100 | |
28 | @@ -39,6 +39,7 @@ | |
29 | #include "interps.h" | |
30 | #include "mi/mi-cmds.h" | |
31 | #include "target.h" | |
32 | +#include "gdb_assert.h" | |
33 | ||
34 | /* We share this one with symtab.c, but it is not exported widely. */ | |
35 | ||
36 | @@ -78,7 +79,8 @@ static struct symtabs_and_lines find_met | |
37 | ||
38 | static int collect_methods (char *copy, struct type *t, | |
39 | struct symbol *sym_class, | |
40 | - struct symbol **sym_arr); | |
41 | + struct symbol **sym_arr, | |
42 | + struct minimal_symbol **msym_arr); | |
43 | ||
44 | static NORETURN void cplusplus_error (const char *name, | |
45 | const char *fmt, ...) | |
46 | @@ -87,11 +89,13 @@ static NORETURN void cplusplus_error (co | |
47 | static int total_number_of_methods (struct type *type); | |
48 | ||
49 | static int find_methods (struct type *, char *, | |
50 | - enum language, struct symbol **); | |
51 | + enum language, struct symbol **, | |
52 | + struct minimal_symbol **); | |
53 | ||
54 | static int add_matching_methods (int method_counter, struct type *t, | |
55 | enum language language, | |
56 | - struct symbol **sym_arr); | |
57 | + struct symbol **sym_arr, | |
58 | + struct minimal_symbol **msym_arr); | |
59 | ||
60 | static int add_constructors (int method_counter, struct type *t, | |
61 | enum language language, | |
62 | @@ -107,6 +111,9 @@ static int is_objc_method_format (const | |
63 | static struct symtabs_and_lines decode_line_2 (struct symbol *[], | |
64 | int, int, char ***); | |
65 | ||
66 | +static struct symtabs_and_lines decode_line_3 (struct minimal_symbol *[], | |
67 | + int, int, char ***); | |
68 | + | |
69 | static struct symtab *symtab_from_filename (char **argptr, | |
70 | char *p, int is_quote_enclosed, | |
71 | int *not_found_ptr); | |
72 | @@ -196,13 +203,18 @@ total_number_of_methods (struct type *ty | |
73 | /* Recursive helper function for decode_line_1. | |
74 | Look for methods named NAME in type T. | |
75 | Return number of matches. | |
76 | - Put matches in SYM_ARR, which should have been allocated with | |
77 | + Put symbol matches in SYM_ARR, which should have been allocated with | |
78 | a size of total_number_of_methods (T) * sizeof (struct symbol *). | |
79 | + In a special case where we are looking for constructors, we may | |
80 | + have to return minimal symbols in the array: MSYM_ARR. This occurs | |
81 | + when the compiler does not generate mangled names for the constructor's | |
82 | + debug info because there are multiple versions of the constructor | |
83 | + (in-charge vs not-in-charge). | |
84 | Note that this function is g++ specific. */ | |
85 | ||
86 | static int | |
87 | find_methods (struct type *t, char *name, enum language language, | |
88 | - struct symbol **sym_arr) | |
89 | + struct symbol **sym_arr, struct minimal_symbol **msym_arr) | |
90 | { | |
91 | int i1 = 0; | |
92 | int ibase; | |
93 | @@ -244,7 +256,7 @@ find_methods (struct type *t, char *name | |
94 | if (strcmp_iw (name, method_name) == 0) | |
95 | /* Find all the overloaded methods with that name. */ | |
96 | i1 += add_matching_methods (method_counter, t, language, | |
97 | - sym_arr + i1); | |
98 | + sym_arr + i1, msym_arr); | |
99 | else if (strncmp (class_name, name, name_len) == 0 | |
100 | && (class_name[name_len] == '\0' | |
101 | || class_name[name_len] == '<')) | |
102 | @@ -267,21 +279,100 @@ find_methods (struct type *t, char *name | |
103 | if (i1 == 0) | |
104 | for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) | |
105 | i1 += find_methods (TYPE_BASECLASS (t, ibase), name, | |
106 | - language, sym_arr + i1); | |
107 | + language, sym_arr + i1, msym_arr); | |
108 | ||
109 | return i1; | |
110 | } | |
111 | ||
112 | +static int | |
113 | +add_minsym_members (const char *class_name, | |
114 | + const char *member_name, | |
115 | + struct minimal_symbol **msym_arr) | |
116 | +{ | |
117 | + char *completion_name; | |
118 | + char **list; | |
119 | + int i; | |
120 | + int comp_len; | |
121 | + int counter = 0; | |
122 | + | |
123 | + /* To find the member, we first cheat and use symbol completion. | |
124 | + This will give us a list of all the member names including | |
125 | + the function signature. */ | |
126 | + completion_name = xmalloc (strlen (class_name) + | |
127 | + strlen (member_name) + 9); | |
128 | + completion_name[0] = '\''; | |
129 | + strcpy (completion_name+1, class_name); | |
130 | + /* FIXME: make this the language class separator. */ | |
131 | + strcat (completion_name, "::"); | |
132 | + strcat (completion_name, member_name); | |
133 | + strcat (completion_name, "("); | |
134 | + list = make_symbol_completion_list (completion_name, | |
135 | + completion_name+1); | |
136 | + | |
137 | + /* Now that we have the list, we generate an array of their | |
138 | + corresponding minimal symbols. */ | |
139 | + counter = 0; | |
140 | + while (list && list[counter] != NULL) | |
141 | + { | |
142 | + msym_arr[counter] = lookup_minimal_symbol (list[counter], NULL, NULL); | |
143 | + ++counter; | |
144 | + } | |
145 | + | |
146 | + xfree (list); | |
147 | + | |
148 | + /* In the case of constructors, there may be in-charge vs not-in-charge | |
149 | + constructors. Check for names with $base which indicates not-in-charge | |
150 | + constructors. */ | |
151 | + comp_len = strlen (completion_name); | |
152 | + strcpy (completion_name + comp_len - 1, "$base("); | |
153 | + list = make_symbol_completion_list (completion_name, | |
154 | + completion_name+1); | |
155 | + | |
156 | + /* Again we have a list. Add their minimal symbols to the array. */ | |
157 | + i = 0; | |
158 | + while (list && list[i] != NULL) | |
159 | + { | |
160 | + msym_arr[counter] = lookup_minimal_symbol (list[i++], NULL, NULL); | |
161 | + ++counter; | |
162 | + } | |
163 | + xfree (list); | |
164 | + | |
165 | + /* Target also the allocating/deleting variants. */ | |
166 | + if (member_name[0] == '~') | |
167 | + strcpy (completion_name + comp_len - 1, "$delete("); | |
168 | + else | |
169 | + strcpy (completion_name + comp_len - 1, "$allocate("); | |
170 | + list = make_symbol_completion_list (completion_name, | |
171 | + completion_name+1); | |
172 | + | |
173 | + /* Again we have a list. Add their minimal symbols to the array. */ | |
174 | + i = 0; | |
175 | + while (list && list[i] != NULL) | |
176 | + { | |
177 | + msym_arr[counter] = lookup_minimal_symbol (list[i++], NULL, NULL); | |
178 | + ++counter; | |
179 | + } | |
180 | + xfree (list); | |
181 | + | |
182 | + xfree (completion_name); | |
183 | + | |
184 | + return counter; | |
185 | +} | |
186 | + | |
187 | /* Add the symbols associated to methods of the class whose type is T | |
188 | and whose name matches the method indexed by METHOD_COUNTER in the | |
189 | array SYM_ARR. Return the number of methods added. */ | |
190 | ||
191 | static int | |
192 | add_matching_methods (int method_counter, struct type *t, | |
193 | - enum language language, struct symbol **sym_arr) | |
194 | + enum language language, struct symbol **sym_arr, | |
195 | + struct minimal_symbol **msym_arr) | |
196 | { | |
197 | int field_counter; | |
198 | int i1 = 0; | |
199 | + int cons_index = 0; | |
200 | + char *class_name = type_name_no_tag (t); | |
201 | + char **list = NULL; | |
202 | ||
203 | for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1; | |
204 | field_counter >= 0; | |
205 | @@ -306,6 +397,16 @@ add_matching_methods (int method_counter | |
206 | else | |
207 | phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); | |
208 | ||
209 | + /* Check for special case of looking for member that | |
210 | + doesn't have a mangled name provided. This will happen | |
211 | + when we have in-charge and not-in-charge constructors. | |
212 | + Since we don't have a mangled name to work with, if we | |
213 | + look for the symbol, we can only find the class itself. | |
214 | + We can find the information we need in the minimal symbol | |
215 | + table which has the full member name information we need. */ | |
216 | + if (strlen (phys_name) <= strlen (class_name)) | |
217 | + return add_minsym_members (class_name, phys_name, msym_arr); | |
218 | + | |
219 | /* Destructor is handled by caller, don't add it to | |
220 | the list. */ | |
221 | if (is_destructor_name (phys_name) != 0) | |
222 | @@ -330,6 +431,9 @@ add_matching_methods (int method_counter | |
223 | } | |
224 | } | |
225 | ||
226 | + if (list) | |
227 | + xfree (list); | |
228 | + | |
229 | return i1; | |
230 | } | |
231 | ||
232 | @@ -630,6 +734,146 @@ See set/show multiple-symbol.")); | |
233 | discard_cleanups (old_chain); | |
234 | return return_values; | |
235 | } | |
236 | + | |
237 | +/* Given a list of NELTS minimal symbols in MSYM_ARR, return a list of lines to | |
238 | + operate on (ask user if necessary). | |
239 | + If CANONICAL is non-NULL return a corresponding array of mangled names | |
240 | + as canonical line specs there. */ | |
241 | + | |
242 | +static struct symtabs_and_lines | |
243 | +decode_line_3 (struct minimal_symbol *msym_arr[], | |
244 | + int nelts, int funfirstline, | |
245 | + char ***canonical) | |
246 | +{ | |
247 | + struct symtabs_and_lines values, return_values; | |
248 | + char *args, *arg1; | |
249 | + int i; | |
250 | + char *prompt; | |
251 | + char *symname; | |
252 | + struct cleanup *old_chain; | |
253 | + char **canonical_arr = (char **) NULL; | |
254 | + | |
255 | + values.sals = (struct symtab_and_line *) | |
256 | + alloca (nelts * sizeof (struct symtab_and_line)); | |
257 | + return_values.sals = (struct symtab_and_line *) | |
258 | + xmalloc (nelts * sizeof (struct symtab_and_line)); | |
259 | + old_chain = make_cleanup (xfree, return_values.sals); | |
260 | + | |
261 | + if (canonical) | |
262 | + { | |
263 | + canonical_arr = (char **) xmalloc (nelts * sizeof (char *)); | |
264 | + make_cleanup (xfree, canonical_arr); | |
265 | + memset (canonical_arr, 0, nelts * sizeof (char *)); | |
266 | + *canonical = canonical_arr; | |
267 | + } | |
268 | + | |
269 | + i = 0; | |
270 | + printf_unfiltered ("[0] cancel\n[1] all\n"); | |
271 | + while (i < nelts) | |
272 | + { | |
273 | + init_sal (&return_values.sals[i]); /* Initialize to zeroes. */ | |
274 | + init_sal (&values.sals[i]); | |
275 | + if (msym_arr[i]) | |
276 | + { | |
277 | + struct symtabs_and_lines msal = minsym_found (funfirstline, | |
278 | + msym_arr[i]); | |
279 | + memcpy (&values.sals[i], &msal.sals[0], | |
280 | + sizeof (struct symtab_and_line)); | |
281 | + if (values.sals[i].symtab) | |
282 | + printf_unfiltered ("[%d] %s at %s:%d\n", | |
283 | + (i + 2), | |
284 | + SYMBOL_PRINT_NAME (msym_arr[i]), | |
285 | + values.sals[i].symtab->filename, | |
286 | + values.sals[i].line); | |
287 | + else | |
288 | + printf_unfiltered ("[%d] %s at ?FILE:%d [No symtab? Probably broken debug info...]\n", | |
289 | + (i + 2), | |
290 | + SYMBOL_PRINT_NAME (msym_arr[i]), | |
291 | + values.sals[i].line); | |
292 | + | |
293 | + } | |
294 | + else | |
295 | + printf_unfiltered ("?HERE\n"); | |
296 | + i++; | |
297 | + } | |
298 | + | |
299 | + prompt = getenv ("PS2"); | |
300 | + if (prompt == NULL) | |
301 | + { | |
302 | + prompt = "> "; | |
303 | + } | |
304 | + args = command_line_input (prompt, 0, "overload-choice"); | |
305 | + | |
306 | + if (args == 0 || *args == 0) | |
307 | + error_no_arg ("one or more choice numbers"); | |
308 | + | |
309 | + i = 0; | |
310 | + while (*args) | |
311 | + { | |
312 | + int num; | |
313 | + | |
314 | + arg1 = args; | |
315 | + while (*arg1 >= '0' && *arg1 <= '9') | |
316 | + arg1++; | |
317 | + if (*arg1 && *arg1 != ' ' && *arg1 != '\t') | |
318 | + error ("Arguments must be choice numbers."); | |
319 | + | |
320 | + num = atoi (args); | |
321 | + | |
322 | + if (num == 0) | |
323 | + error ("canceled"); | |
324 | + else if (num == 1) | |
325 | + { | |
326 | + if (canonical_arr) | |
327 | + { | |
328 | + for (i = 0; i < nelts; i++) | |
329 | + { | |
330 | + if (canonical_arr[i] == NULL) | |
331 | + { | |
332 | + symname = SYMBOL_LINKAGE_NAME (msym_arr[i]); | |
333 | + canonical_arr[i] = savestring (symname, strlen (symname)); | |
334 | + } | |
335 | + } | |
336 | + } | |
337 | + memcpy (return_values.sals, values.sals, | |
338 | + (nelts * sizeof (struct symtab_and_line))); | |
339 | + return_values.nelts = nelts; | |
340 | + discard_cleanups (old_chain); | |
341 | + return return_values; | |
342 | + } | |
343 | + | |
344 | + if (num >= nelts + 2) | |
345 | + { | |
346 | + printf_unfiltered ("No choice number %d.\n", num); | |
347 | + } | |
348 | + else | |
349 | + { | |
350 | + num -= 2; | |
351 | + if (values.sals[num].pc) | |
352 | + { | |
353 | + if (canonical_arr) | |
354 | + { | |
355 | + symname = SYMBOL_LINKAGE_NAME (msym_arr[num]); | |
356 | + make_cleanup (xfree, symname); | |
357 | + canonical_arr[i] = savestring (symname, strlen (symname)); | |
358 | + } | |
359 | + return_values.sals[i++] = values.sals[num]; | |
360 | + values.sals[num].pc = 0; | |
361 | + } | |
362 | + else | |
363 | + { | |
364 | + printf_unfiltered ("duplicate request for %d ignored.\n", num); | |
365 | + } | |
366 | + } | |
367 | + | |
368 | + args = arg1; | |
369 | + while (*args == ' ' || *args == '\t') | |
370 | + args++; | |
371 | + } | |
372 | + return_values.nelts = i; | |
373 | + discard_cleanups (old_chain); | |
374 | + return return_values; | |
375 | +} | |
376 | \f | |
377 | /* The parser of linespec itself. */ | |
378 | ||
379 | @@ -1438,35 +1682,47 @@ find_method (int funfirstline, char ***c | |
380 | struct symbol **sym_arr = alloca (total_number_of_methods (t) | |
381 | * sizeof (struct symbol *)); | |
382 | ||
383 | + struct minimal_symbol **msym_arr = alloca (total_number_of_methods (t) | |
384 | + * sizeof (struct minimal_symbol *)); | |
385 | + | |
386 | + msym_arr[0] = NULL; | |
387 | + | |
388 | /* Find all methods with a matching name, and put them in | |
389 | sym_arr. */ | |
390 | ||
391 | - i1 = collect_methods (copy, t, sym_class, sym_arr); | |
392 | + i1 = collect_methods (copy, t, sym_class, sym_arr, msym_arr); | |
393 | ||
394 | if (i1 == 1) | |
395 | { | |
396 | /* There is exactly one field with that name. */ | |
397 | - sym = sym_arr[0]; | |
398 | - | |
399 | - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) | |
400 | - { | |
401 | - values.sals = (struct symtab_and_line *) | |
402 | - xmalloc (sizeof (struct symtab_and_line)); | |
403 | - values.nelts = 1; | |
404 | - values.sals[0] = find_function_start_sal (sym, | |
405 | - funfirstline); | |
406 | - } | |
407 | + if (msym_arr[0] != NULL) | |
408 | + return minsym_found (funfirstline, msym_arr[0]); | |
409 | else | |
410 | { | |
411 | - values.sals = NULL; | |
412 | - values.nelts = 0; | |
413 | + sym = sym_arr[0]; | |
414 | + | |
415 | + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) | |
416 | + { | |
417 | + values.sals = (struct symtab_and_line *) | |
418 | + xmalloc (sizeof (struct symtab_and_line)); | |
419 | + values.nelts = 1; | |
420 | + values.sals[0] = find_function_start_sal (sym, | |
421 | + funfirstline); | |
422 | + } | |
423 | + else | |
424 | + { | |
425 | + values.sals = NULL; | |
426 | + values.nelts = 0; | |
427 | + } | |
428 | + return values; | |
429 | } | |
430 | - return values; | |
431 | } | |
432 | if (i1 > 0) | |
433 | { | |
434 | /* There is more than one field with that name | |
435 | (overloaded). Ask the user which one to use. */ | |
436 | + if (msym_arr[0] != NULL) | |
437 | + return decode_line_3 (msym_arr, i1, funfirstline, canonical); | |
438 | return decode_line_2 (sym_arr, i1, funfirstline, canonical); | |
439 | } | |
440 | else | |
441 | @@ -1493,11 +1748,12 @@ find_method (int funfirstline, char ***c | |
442 | } | |
443 | ||
444 | /* Find all methods named COPY in the class whose type is T, and put | |
445 | - them in SYM_ARR. Return the number of methods found. */ | |
446 | + them in SYM_ARR or MSYM_ARR. Return the number of methods found. */ | |
447 | ||
448 | static int | |
449 | collect_methods (char *copy, struct type *t, | |
450 | - struct symbol *sym_class, struct symbol **sym_arr) | |
451 | + struct symbol *sym_class, struct symbol **sym_arr, | |
452 | + struct minimal_symbol **msym_arr) | |
453 | { | |
454 | int i1 = 0; /* Counter for the symbol array. */ | |
455 | ||
456 | @@ -1518,7 +1774,7 @@ collect_methods (char *copy, struct type | |
457 | } | |
458 | } | |
459 | else | |
460 | - i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr); | |
461 | + i1 = find_methods (t, copy, SYMBOL_LANGUAGE (sym_class), sym_arr, msym_arr); | |
462 | ||
463 | return i1; | |
464 | } |