Commit | Line | Data |
---|---|---|
fb40c209 | 1 | /* MI Command Set - stack commands. |
28e7fd62 | 2 | Copyright (C) 2000-2013 Free Software Foundation, Inc. |
ab91fdd5 | 3 | Contributed by Cygnus Solutions (a Red Hat company). |
fb40c209 AC |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
a9762ec7 | 9 | the Free Software Foundation; either version 3 of the License, or |
fb40c209 AC |
10 | (at your option) any later version. |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
a9762ec7 | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
fb40c209 AC |
19 | |
20 | #include "defs.h" | |
21 | #include "target.h" | |
22 | #include "frame.h" | |
23 | #include "value.h" | |
24 | #include "mi-cmds.h" | |
25 | #include "ui-out.h" | |
e88c90f2 | 26 | #include "symtab.h" |
fe898f56 | 27 | #include "block.h" |
b9362cc7 | 28 | #include "stack.h" |
de4f826b | 29 | #include "dictionary.h" |
f5ec2042 | 30 | #include "gdb_string.h" |
d8ca156b | 31 | #include "language.h" |
79a45b7d | 32 | #include "valprint.h" |
875b4ff5 | 33 | #include "exceptions.h" |
1e611234 PM |
34 | #include "utils.h" |
35 | #include "mi-getopt.h" | |
36 | #include "python/python.h" | |
37 | #include <ctype.h> | |
87967e27 | 38 | #include "mi-parse.h" |
daf3c977 VP |
39 | |
40 | enum what_to_list { locals, arguments, all }; | |
41 | ||
42 | static void list_args_or_locals (enum what_to_list what, | |
bdaf8d4a JK |
43 | enum print_values values, |
44 | struct frame_info *fi); | |
fb40c209 | 45 | |
1e611234 PM |
46 | /* True if we want to allow Python-based frame filters. */ |
47 | static int frame_filters = 0; | |
48 | ||
49 | void | |
50 | mi_cmd_enable_frame_filters (char *command, char **argv, int argc) | |
51 | { | |
52 | if (argc != 0) | |
53 | error (_("-enable-frame-filters: no arguments allowed")); | |
54 | frame_filters = 1; | |
55 | } | |
56 | ||
2b03b41d | 57 | /* Print a list of the stack frames. Args can be none, in which case |
fb40c209 AC |
58 | we want to print the whole backtrace, or a pair of numbers |
59 | specifying the frame numbers at which to start and stop the | |
2b03b41d SS |
60 | display. If the two numbers are equal, a single frame will be |
61 | displayed. */ | |
62 | ||
ce8f13f8 | 63 | void |
fb40c209 AC |
64 | mi_cmd_stack_list_frames (char *command, char **argv, int argc) |
65 | { | |
66 | int frame_low; | |
67 | int frame_high; | |
68 | int i; | |
6ad4a2cf | 69 | struct cleanup *cleanup_stack; |
fb40c209 | 70 | struct frame_info *fi; |
1e611234 PM |
71 | enum py_bt_status result = PY_BT_ERROR; |
72 | int raw_arg = 0; | |
73 | int oind = 0; | |
74 | enum opt | |
75 | { | |
76 | NO_FRAME_FILTERS | |
77 | }; | |
78 | static const struct mi_opt opts[] = | |
79 | { | |
80 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
81 | { 0, 0, 0 } | |
82 | }; | |
83 | ||
84 | /* Parse arguments. In this instance we are just looking for | |
85 | --no-frame-filters. */ | |
86 | while (1) | |
87 | { | |
88 | char *oarg; | |
89 | int opt = mi_getopt ("-stack-list-frames", argc, argv, | |
90 | opts, &oind, &oarg); | |
91 | if (opt < 0) | |
92 | break; | |
93 | switch ((enum opt) opt) | |
94 | { | |
95 | case NO_FRAME_FILTERS: | |
96 | raw_arg = oind; | |
97 | break; | |
98 | } | |
99 | } | |
fb40c209 | 100 | |
1e611234 PM |
101 | /* After the last option is parsed, there should either be low - |
102 | high range, or no further arguments. */ | |
103 | if ((argc - oind != 0) && (argc - oind != 2)) | |
104 | error (_("-stack-list-frames: Usage: [--no-frame-filters] [FRAME_LOW FRAME_HIGH]")); | |
fb40c209 | 105 | |
1e611234 PM |
106 | /* If there is a range, set it. */ |
107 | if (argc - oind == 2) | |
fb40c209 | 108 | { |
1e611234 PM |
109 | frame_low = atoi (argv[0 + oind]); |
110 | frame_high = atoi (argv[1 + oind]); | |
fb40c209 AC |
111 | } |
112 | else | |
113 | { | |
114 | /* Called with no arguments, it means we want the whole | |
2b03b41d | 115 | backtrace. */ |
fb40c209 AC |
116 | frame_low = -1; |
117 | frame_high = -1; | |
118 | } | |
119 | ||
120 | /* Let's position fi on the frame at which to start the | |
121 | display. Could be the innermost frame if the whole stack needs | |
2b03b41d | 122 | displaying, or if frame_low is 0. */ |
fb40c209 AC |
123 | for (i = 0, fi = get_current_frame (); |
124 | fi && i < frame_low; | |
125 | i++, fi = get_prev_frame (fi)); | |
126 | ||
127 | if (fi == NULL) | |
1b05df00 | 128 | error (_("-stack-list-frames: Not enough frames in stack.")); |
fb40c209 | 129 | |
79a45e25 | 130 | cleanup_stack = make_cleanup_ui_out_list_begin_end (current_uiout, "stack"); |
fb40c209 | 131 | |
1e611234 | 132 | if (! raw_arg && frame_filters) |
fb40c209 | 133 | { |
1e611234 PM |
134 | int flags = PRINT_LEVEL | PRINT_FRAME_INFO; |
135 | int py_frame_low = frame_low; | |
136 | ||
137 | /* We cannot pass -1 to frame_low, as that would signify a | |
138 | relative backtrace from the tail of the stack. So, in the case | |
139 | of frame_low == -1, assign and increment it. */ | |
140 | if (py_frame_low == -1) | |
141 | py_frame_low++; | |
142 | ||
143 | result = apply_frame_filter (get_current_frame (), flags, | |
144 | NO_VALUES, current_uiout, | |
145 | py_frame_low, frame_high); | |
146 | } | |
147 | ||
148 | /* Run the inbuilt backtrace if there are no filters registered, or | |
149 | if "--no-frame-filters" has been specified from the command. */ | |
150 | if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS) | |
151 | { | |
152 | /* Now let's print the frames up to frame_high, or until there are | |
153 | frames in the stack. */ | |
154 | for (; | |
155 | fi && (i <= frame_high || frame_high == -1); | |
156 | i++, fi = get_prev_frame (fi)) | |
157 | { | |
158 | QUIT; | |
159 | /* Print the location and the address always, even for level 0. | |
160 | If args is 0, don't print the arguments. */ | |
161 | print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* args */ ); | |
162 | } | |
fb40c209 AC |
163 | } |
164 | ||
6ad4a2cf | 165 | do_cleanups (cleanup_stack); |
fb40c209 AC |
166 | } |
167 | ||
ce8f13f8 | 168 | void |
fb40c209 AC |
169 | mi_cmd_stack_info_depth (char *command, char **argv, int argc) |
170 | { | |
171 | int frame_high; | |
172 | int i; | |
173 | struct frame_info *fi; | |
174 | ||
fb40c209 | 175 | if (argc > 1) |
1b05df00 | 176 | error (_("-stack-info-depth: Usage: [MAX_DEPTH]")); |
fb40c209 AC |
177 | |
178 | if (argc == 1) | |
179 | frame_high = atoi (argv[0]); | |
180 | else | |
181 | /* Called with no arguments, it means we want the real depth of | |
2b03b41d | 182 | the stack. */ |
fb40c209 AC |
183 | frame_high = -1; |
184 | ||
185 | for (i = 0, fi = get_current_frame (); | |
186 | fi && (i < frame_high || frame_high == -1); | |
187 | i++, fi = get_prev_frame (fi)) | |
188 | QUIT; | |
189 | ||
79a45e25 | 190 | ui_out_field_int (current_uiout, "depth", i); |
fb40c209 AC |
191 | } |
192 | ||
7a93fb82 | 193 | /* Print a list of the locals for the current frame. With argument of |
fb40c209 | 194 | 0, print only the names, with argument of 1 print also the |
2b03b41d SS |
195 | values. */ |
196 | ||
ce8f13f8 | 197 | void |
fb40c209 AC |
198 | mi_cmd_stack_list_locals (char *command, char **argv, int argc) |
199 | { | |
f5ec2042 | 200 | struct frame_info *frame; |
1e611234 PM |
201 | int raw_arg = 0; |
202 | enum py_bt_status result = PY_BT_ERROR; | |
203 | int print_value; | |
645eab03 | 204 | int oind = 0; |
f5ec2042 | 205 | |
645eab03 YQ |
206 | if (argc > 1) |
207 | { | |
208 | int i; | |
209 | enum opt | |
210 | { | |
211 | NO_FRAME_FILTERS | |
212 | }; | |
213 | static const struct mi_opt opts[] = | |
214 | { | |
215 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
216 | { 0, 0, 0 } | |
217 | }; | |
218 | ||
219 | while (1) | |
220 | { | |
221 | char *oarg; | |
222 | /* Don't parse 'print-values' as an option. */ | |
223 | int opt = mi_getopt ("-stack-list-locals", argc - 1, argv, | |
224 | opts, &oind, &oarg); | |
225 | ||
226 | if (opt < 0) | |
227 | break; | |
228 | switch ((enum opt) opt) | |
229 | { | |
230 | case NO_FRAME_FILTERS: | |
231 | raw_arg = oind; | |
232 | break; | |
233 | } | |
234 | } | |
235 | } | |
fb40c209 | 236 | |
645eab03 YQ |
237 | /* After the last option is parsed, there should be only |
238 | 'print-values'. */ | |
239 | if (argc - oind != 1) | |
1e611234 | 240 | error (_("-stack-list-locals: Usage: [--no-frame-filters] PRINT_VALUES")); |
f5ec2042 | 241 | |
1e611234 | 242 | frame = get_selected_frame (NULL); |
645eab03 | 243 | print_value = mi_parse_print_values (argv[oind]); |
1e611234 PM |
244 | |
245 | if (! raw_arg && frame_filters) | |
246 | { | |
247 | int flags = PRINT_LEVEL | PRINT_LOCALS; | |
248 | ||
249 | result = apply_frame_filter (frame, flags, print_value, | |
250 | current_uiout, 0, 0); | |
251 | } | |
252 | ||
253 | /* Run the inbuilt backtrace if there are no filters registered, or | |
254 | if "--no-frame-filters" has been specified from the command. */ | |
255 | if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS) | |
256 | { | |
257 | list_args_or_locals (locals, print_value, frame); | |
258 | } | |
fb40c209 AC |
259 | } |
260 | ||
7a93fb82 | 261 | /* Print a list of the arguments for the current frame. With argument |
fb40c209 | 262 | of 0, print only the names, with argument of 1 print also the |
2b03b41d SS |
263 | values. */ |
264 | ||
ce8f13f8 | 265 | void |
fb40c209 AC |
266 | mi_cmd_stack_list_args (char *command, char **argv, int argc) |
267 | { | |
268 | int frame_low; | |
269 | int frame_high; | |
270 | int i; | |
271 | struct frame_info *fi; | |
6ad4a2cf | 272 | struct cleanup *cleanup_stack_args; |
8b777f02 | 273 | enum print_values print_values; |
79a45e25 | 274 | struct ui_out *uiout = current_uiout; |
1e611234 | 275 | int raw_arg = 0; |
242f1fd7 | 276 | int oind = 0; |
1e611234 | 277 | enum py_bt_status result = PY_BT_ERROR; |
242f1fd7 YQ |
278 | enum opt |
279 | { | |
280 | NO_FRAME_FILTERS, | |
281 | }; | |
282 | static const struct mi_opt opts[] = | |
283 | { | |
284 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
285 | { 0, 0, 0 } | |
286 | }; | |
287 | ||
288 | while (1) | |
289 | { | |
290 | char *oarg; | |
291 | int opt = mi_getopt_allow_unknown ("-stack-list-args", argc, argv, | |
292 | opts, &oind, &oarg); | |
fb40c209 | 293 | |
242f1fd7 YQ |
294 | if (opt < 0) |
295 | break; | |
296 | switch ((enum opt) opt) | |
297 | { | |
298 | case NO_FRAME_FILTERS: | |
299 | raw_arg = oind; | |
300 | break; | |
301 | } | |
302 | } | |
fb40c209 | 303 | |
242f1fd7 YQ |
304 | if (argc - oind != 1 && argc - oind != 3) |
305 | error (_("-stack-list-arguments: Usage: " \ | |
1e611234 PM |
306 | "[--no-frame-filters] PRINT_VALUES [FRAME_LOW FRAME_HIGH]")); |
307 | ||
242f1fd7 | 308 | if (argc - oind == 3) |
fb40c209 | 309 | { |
242f1fd7 YQ |
310 | frame_low = atoi (argv[1 + oind]); |
311 | frame_high = atoi (argv[2 + oind]); | |
fb40c209 AC |
312 | } |
313 | else | |
314 | { | |
315 | /* Called with no arguments, it means we want args for the whole | |
2b03b41d | 316 | backtrace. */ |
fb40c209 AC |
317 | frame_low = -1; |
318 | frame_high = -1; | |
319 | } | |
320 | ||
242f1fd7 | 321 | print_values = mi_parse_print_values (argv[oind]); |
8b777f02 | 322 | |
fb40c209 AC |
323 | /* Let's position fi on the frame at which to start the |
324 | display. Could be the innermost frame if the whole stack needs | |
2b03b41d | 325 | displaying, or if frame_low is 0. */ |
fb40c209 AC |
326 | for (i = 0, fi = get_current_frame (); |
327 | fi && i < frame_low; | |
328 | i++, fi = get_prev_frame (fi)); | |
329 | ||
330 | if (fi == NULL) | |
1b05df00 | 331 | error (_("-stack-list-arguments: Not enough frames in stack.")); |
fb40c209 | 332 | |
9a2b4c1b MS |
333 | cleanup_stack_args |
334 | = make_cleanup_ui_out_list_begin_end (uiout, "stack-args"); | |
fb40c209 | 335 | |
1e611234 | 336 | if (! raw_arg && frame_filters) |
fb40c209 | 337 | { |
1e611234 PM |
338 | int flags = PRINT_LEVEL | PRINT_ARGS; |
339 | int py_frame_low = frame_low; | |
340 | ||
341 | /* We cannot pass -1 to frame_low, as that would signify a | |
342 | relative backtrace from the tail of the stack. So, in the case | |
343 | of frame_low == -1, assign and increment it. */ | |
344 | if (py_frame_low == -1) | |
345 | py_frame_low++; | |
346 | ||
347 | result = apply_frame_filter (get_current_frame (), flags, | |
348 | print_values, current_uiout, | |
349 | py_frame_low, frame_high); | |
fb40c209 AC |
350 | } |
351 | ||
1e611234 PM |
352 | /* Run the inbuilt backtrace if there are no filters registered, or |
353 | if "--no-frame-filters" has been specified from the command. */ | |
354 | if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS) | |
355 | { | |
356 | /* Now let's print the frames up to frame_high, or until there are | |
357 | frames in the stack. */ | |
358 | for (; | |
359 | fi && (i <= frame_high || frame_high == -1); | |
360 | i++, fi = get_prev_frame (fi)) | |
361 | { | |
362 | struct cleanup *cleanup_frame; | |
363 | ||
364 | QUIT; | |
365 | cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); | |
366 | ui_out_field_int (uiout, "level", i); | |
367 | list_args_or_locals (arguments, print_values, fi); | |
368 | do_cleanups (cleanup_frame); | |
369 | } | |
370 | } | |
6ad4a2cf | 371 | do_cleanups (cleanup_stack_args); |
fb40c209 AC |
372 | } |
373 | ||
daf3c977 | 374 | /* Print a list of the local variables (including arguments) for the |
7a93fb82 VP |
375 | current frame. ARGC must be 1 and ARGV[0] specify if only the names, |
376 | or both names and values of the variables must be printed. See | |
377 | parse_print_value for possible values. */ | |
2b03b41d | 378 | |
daf3c977 VP |
379 | void |
380 | mi_cmd_stack_list_variables (char *command, char **argv, int argc) | |
381 | { | |
382 | struct frame_info *frame; | |
1e611234 PM |
383 | int raw_arg = 0; |
384 | enum py_bt_status result = PY_BT_ERROR; | |
385 | int print_value; | |
645eab03 | 386 | int oind = 0; |
daf3c977 | 387 | |
645eab03 YQ |
388 | if (argc > 1) |
389 | { | |
390 | int i; | |
391 | enum opt | |
392 | { | |
393 | NO_FRAME_FILTERS | |
394 | }; | |
395 | static const struct mi_opt opts[] = | |
396 | { | |
397 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
398 | { 0, 0, 0 } | |
399 | }; | |
400 | ||
401 | while (1) | |
402 | { | |
403 | char *oarg; | |
404 | /* Don't parse 'print-values' as an option. */ | |
405 | int opt = mi_getopt ("-stack-list-variables", argc - 1, | |
406 | argv, opts, &oind, &oarg); | |
407 | if (opt < 0) | |
408 | break; | |
409 | switch ((enum opt) opt) | |
410 | { | |
411 | case NO_FRAME_FILTERS: | |
412 | raw_arg = oind; | |
413 | break; | |
414 | } | |
415 | } | |
416 | } | |
daf3c977 | 417 | |
645eab03 YQ |
418 | /* After the last option is parsed, there should be only |
419 | 'print-values'. */ | |
420 | if (argc - oind != 1) | |
1e611234 PM |
421 | error (_("-stack-list-variables: Usage: " \ |
422 | "[--no-frame-filters] PRINT_VALUES")); | |
daf3c977 | 423 | |
1e611234 | 424 | frame = get_selected_frame (NULL); |
645eab03 | 425 | print_value = mi_parse_print_values (argv[oind]); |
1e611234 PM |
426 | |
427 | if (! raw_arg && frame_filters) | |
428 | { | |
429 | int flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS; | |
430 | ||
431 | result = apply_frame_filter (frame, flags, print_value, | |
432 | current_uiout, 0, 0); | |
433 | } | |
434 | ||
435 | /* Run the inbuilt backtrace if there are no filters registered, or | |
436 | if "--no-frame-filters" has been specified from the command. */ | |
437 | if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS) | |
438 | { | |
439 | list_args_or_locals (all, print_value, frame); | |
440 | } | |
daf3c977 VP |
441 | } |
442 | ||
2b03b41d SS |
443 | /* Print single local or argument. ARG must be already read in. For |
444 | WHAT and VALUES see list_args_or_locals. | |
93d86cef | 445 | |
2b03b41d SS |
446 | Errors are printed as if they would be the parameter value. Use |
447 | zeroed ARG iff it should not be printed according to VALUES. */ | |
93d86cef JK |
448 | |
449 | static void | |
450 | list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, | |
451 | enum print_values values) | |
452 | { | |
f99d8bf4 | 453 | struct cleanup *old_chain; |
93d86cef | 454 | struct ui_out *uiout = current_uiout; |
f99d8bf4 PA |
455 | struct ui_file *stb; |
456 | ||
457 | stb = mem_fileopen (); | |
458 | old_chain = make_cleanup_ui_file_delete (stb); | |
93d86cef JK |
459 | |
460 | gdb_assert (!arg->val || !arg->error); | |
461 | gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL | |
462 | && arg->error == NULL) | |
463 | || values == PRINT_SIMPLE_VALUES | |
464 | || (values == PRINT_ALL_VALUES | |
465 | && (arg->val != NULL || arg->error != NULL))); | |
e18b2753 JK |
466 | gdb_assert (arg->entry_kind == print_entry_values_no |
467 | || (arg->entry_kind == print_entry_values_only | |
468 | && (arg->val || arg->error))); | |
93d86cef JK |
469 | |
470 | if (values != PRINT_NO_VALUES || what == all) | |
cd82eddc | 471 | make_cleanup_ui_out_tuple_begin_end (uiout, NULL); |
93d86cef | 472 | |
f99d8bf4 | 473 | fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb); |
e18b2753 | 474 | if (arg->entry_kind == print_entry_values_only) |
f99d8bf4 | 475 | fputs_filtered ("@entry", stb); |
e18b2753 | 476 | ui_out_field_stream (uiout, "name", stb); |
93d86cef JK |
477 | |
478 | if (what == all && SYMBOL_IS_ARGUMENT (arg->sym)) | |
479 | ui_out_field_int (uiout, "arg", 1); | |
480 | ||
481 | if (values == PRINT_SIMPLE_VALUES) | |
482 | { | |
483 | check_typedef (arg->sym->type); | |
f99d8bf4 | 484 | type_print (arg->sym->type, "", stb, -1); |
93d86cef JK |
485 | ui_out_field_stream (uiout, "type", stb); |
486 | } | |
487 | ||
488 | if (arg->val || arg->error) | |
489 | { | |
490 | volatile struct gdb_exception except; | |
491 | ||
492 | if (arg->error) | |
493 | except.message = arg->error; | |
494 | else | |
495 | { | |
496 | /* TRY_CATCH has two statements, wrap it in a block. */ | |
497 | ||
498 | TRY_CATCH (except, RETURN_MASK_ERROR) | |
499 | { | |
500 | struct value_print_options opts; | |
501 | ||
2a998fc0 | 502 | get_no_prettyformat_print_options (&opts); |
93d86cef | 503 | opts.deref_ref = 1; |
f99d8bf4 | 504 | common_val_print (arg->val, stb, 0, &opts, |
93d86cef JK |
505 | language_def (SYMBOL_LANGUAGE (arg->sym))); |
506 | } | |
507 | } | |
508 | if (except.message) | |
f99d8bf4 | 509 | fprintf_filtered (stb, _("<error reading variable: %s>"), |
93d86cef JK |
510 | except.message); |
511 | ui_out_field_stream (uiout, "value", stb); | |
512 | } | |
513 | ||
f99d8bf4 | 514 | do_cleanups (old_chain); |
93d86cef | 515 | } |
daf3c977 | 516 | |
5c4aa40b YQ |
517 | /* Print a list of the objects for the frame FI in a certain form, |
518 | which is determined by VALUES. The objects can be locals, | |
519 | arguments or both, which is determined by WHAT. */ | |
2b03b41d | 520 | |
fb40c209 | 521 | static void |
bdaf8d4a JK |
522 | list_args_or_locals (enum what_to_list what, enum print_values values, |
523 | struct frame_info *fi) | |
fb40c209 AC |
524 | { |
525 | struct block *block; | |
526 | struct symbol *sym; | |
8157b174 | 527 | struct block_iterator iter; |
6ad4a2cf | 528 | struct cleanup *cleanup_list; |
f5ec2042 | 529 | struct type *type; |
daf3c977 | 530 | char *name_of_result; |
79a45e25 | 531 | struct ui_out *uiout = current_uiout; |
fb40c209 | 532 | |
ae767bfb | 533 | block = get_frame_block (fi, 0); |
fb40c209 | 534 | |
daf3c977 VP |
535 | switch (what) |
536 | { | |
537 | case locals: | |
d6fd4674 PA |
538 | name_of_result = "locals"; |
539 | break; | |
daf3c977 | 540 | case arguments: |
d6fd4674 PA |
541 | name_of_result = "args"; |
542 | break; | |
daf3c977 | 543 | case all: |
d6fd4674 PA |
544 | name_of_result = "variables"; |
545 | break; | |
654e7c1f | 546 | default: |
d6fd4674 PA |
547 | internal_error (__FILE__, __LINE__, |
548 | "unexpected what_to_list: %d", (int) what); | |
daf3c977 VP |
549 | } |
550 | ||
551 | cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, name_of_result); | |
fb40c209 AC |
552 | |
553 | while (block != 0) | |
554 | { | |
de4f826b | 555 | ALL_BLOCK_SYMBOLS (block, iter, sym) |
fb40c209 | 556 | { |
39bf4652 JB |
557 | int print_me = 0; |
558 | ||
fb40c209 AC |
559 | switch (SYMBOL_CLASS (sym)) |
560 | { | |
561 | default: | |
562 | case LOC_UNDEF: /* catches errors */ | |
563 | case LOC_CONST: /* constant */ | |
564 | case LOC_TYPEDEF: /* local typedef */ | |
565 | case LOC_LABEL: /* local label */ | |
566 | case LOC_BLOCK: /* local function */ | |
567 | case LOC_CONST_BYTES: /* loc. byte seq. */ | |
568 | case LOC_UNRESOLVED: /* unresolved static */ | |
569 | case LOC_OPTIMIZED_OUT: /* optimized out */ | |
570 | print_me = 0; | |
571 | break; | |
572 | ||
573 | case LOC_ARG: /* argument */ | |
574 | case LOC_REF_ARG: /* reference arg */ | |
fb40c209 | 575 | case LOC_REGPARM_ADDR: /* indirect register arg */ |
fb40c209 | 576 | case LOC_LOCAL: /* stack local */ |
fb40c209 AC |
577 | case LOC_STATIC: /* static */ |
578 | case LOC_REGISTER: /* register */ | |
4cf623b6 | 579 | case LOC_COMPUTED: /* computed location */ |
daf3c977 | 580 | if (what == all) |
fb40c209 | 581 | print_me = 1; |
daf3c977 VP |
582 | else if (what == locals) |
583 | print_me = !SYMBOL_IS_ARGUMENT (sym); | |
584 | else | |
585 | print_me = SYMBOL_IS_ARGUMENT (sym); | |
fb40c209 AC |
586 | break; |
587 | } | |
588 | if (print_me) | |
589 | { | |
6bb0384f | 590 | struct symbol *sym2; |
e18b2753 | 591 | struct frame_arg arg, entryarg; |
fb40c209 | 592 | |
daf3c977 | 593 | if (SYMBOL_IS_ARGUMENT (sym)) |
f7e44f65 | 594 | sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), |
f5ec2042 | 595 | block, VAR_DOMAIN, |
1993b719 | 596 | NULL); |
f5ec2042 | 597 | else |
2a2d4dc3 | 598 | sym2 = sym; |
f7e44f65 | 599 | gdb_assert (sym2 != NULL); |
93d86cef JK |
600 | |
601 | memset (&arg, 0, sizeof (arg)); | |
602 | arg.sym = sym2; | |
e18b2753 JK |
603 | arg.entry_kind = print_entry_values_no; |
604 | memset (&entryarg, 0, sizeof (entryarg)); | |
605 | entryarg.sym = sym2; | |
606 | entryarg.entry_kind = print_entry_values_no; | |
93d86cef | 607 | |
f5ec2042 NR |
608 | switch (values) |
609 | { | |
610 | case PRINT_SIMPLE_VALUES: | |
611 | type = check_typedef (sym2->type); | |
f5ec2042 NR |
612 | if (TYPE_CODE (type) != TYPE_CODE_ARRAY |
613 | && TYPE_CODE (type) != TYPE_CODE_STRUCT | |
614 | && TYPE_CODE (type) != TYPE_CODE_UNION) | |
615 | { | |
f5ec2042 | 616 | case PRINT_ALL_VALUES: |
82a0a75f YQ |
617 | if (SYMBOL_IS_ARGUMENT (sym)) |
618 | read_frame_arg (sym2, fi, &arg, &entryarg); | |
619 | else | |
620 | read_frame_local (sym2, fi, &arg); | |
93d86cef | 621 | } |
f5ec2042 | 622 | break; |
fb40c209 | 623 | } |
7a93fb82 | 624 | |
e18b2753 JK |
625 | if (arg.entry_kind != print_entry_values_only) |
626 | list_arg_or_local (&arg, what, values); | |
627 | if (entryarg.entry_kind != print_entry_values_no) | |
628 | list_arg_or_local (&entryarg, what, values); | |
93d86cef | 629 | xfree (arg.error); |
e18b2753 | 630 | xfree (entryarg.error); |
fb40c209 AC |
631 | } |
632 | } | |
2b03b41d | 633 | |
fb40c209 AC |
634 | if (BLOCK_FUNCTION (block)) |
635 | break; | |
636 | else | |
637 | block = BLOCK_SUPERBLOCK (block); | |
638 | } | |
6ad4a2cf | 639 | do_cleanups (cleanup_list); |
fb40c209 AC |
640 | } |
641 | ||
ce8f13f8 | 642 | void |
fb40c209 AC |
643 | mi_cmd_stack_select_frame (char *command, char **argv, int argc) |
644 | { | |
fcf43932 | 645 | if (argc == 0 || argc > 1) |
1b05df00 | 646 | error (_("-stack-select-frame: Usage: FRAME_SPEC")); |
fb40c209 | 647 | |
fcf43932 | 648 | select_frame_command (argv[0], 1 /* not used */ ); |
fb40c209 | 649 | } |
64fd8944 | 650 | |
ce8f13f8 | 651 | void |
64fd8944 NR |
652 | mi_cmd_stack_info_frame (char *command, char **argv, int argc) |
653 | { | |
654 | if (argc > 0) | |
2b03b41d | 655 | error (_("-stack-info-frame: No arguments allowed")); |
ce8f13f8 | 656 | |
64fd8944 | 657 | print_frame_info (get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 0); |
64fd8944 | 658 | } |