File: | src/gnu/usr.bin/binutils/gdb/expprint.c |
Warning: | line 85, column 7 Value stored to 'myprec' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Print in infix form a struct expression. |
2 | |
3 | Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, |
4 | 1998, 1999, 2000, 2003 Free Software Foundation, Inc. |
5 | |
6 | This file is part of GDB. |
7 | |
8 | This program is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2 of the License, or |
11 | (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place - Suite 330, |
21 | Boston, MA 02111-1307, USA. */ |
22 | |
23 | #include "defs.h" |
24 | #include "symtab.h" |
25 | #include "gdbtypes.h" |
26 | #include "expression.h" |
27 | #include "value.h" |
28 | #include "language.h" |
29 | #include "parser-defs.h" |
30 | #include "user-regs.h" /* For user_reg_map_regnum_to_name. */ |
31 | #include "target.h" |
32 | #include "gdb_string.h" |
33 | #include "block.h" |
34 | |
35 | #ifdef HAVE_CTYPE_H1 |
36 | #include <ctype.h> |
37 | #endif |
38 | |
39 | void |
40 | print_expression (struct expression *exp, struct ui_file *stream) |
41 | { |
42 | int pc = 0; |
43 | print_subexp (exp, &pc, stream, PREC_NULL); |
44 | } |
45 | |
46 | /* Print the subexpression of EXP that starts in position POS, on STREAM. |
47 | PREC is the precedence of the surrounding operator; |
48 | if the precedence of the main operator of this subexpression is less, |
49 | parentheses are needed here. */ |
50 | |
51 | void |
52 | print_subexp (struct expression *exp, int *pos, |
53 | struct ui_file *stream, enum precedence prec) |
54 | { |
55 | exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec); |
56 | } |
57 | |
58 | /* Standard implementation of print_subexp for use in language_defn |
59 | vectors. */ |
60 | void |
61 | print_subexp_standard (struct expression *exp, int *pos, |
62 | struct ui_file *stream, enum precedence prec) |
63 | { |
64 | unsigned tem; |
65 | const struct op_print *op_print_tab; |
66 | int pc; |
67 | unsigned nargs; |
68 | char *op_str; |
69 | int assign_modify = 0; |
70 | enum exp_opcode opcode; |
71 | enum precedence myprec = PREC_NULL; |
72 | /* Set to 1 for a right-associative operator. */ |
73 | int assoc = 0; |
74 | struct value *val; |
75 | char *tempstr = NULL((void*)0); |
76 | |
77 | op_print_tab = exp->language_defn->la_op_print_tab; |
78 | pc = (*pos)++; |
79 | opcode = exp->elts[pc].opcode; |
80 | switch (opcode) |
81 | { |
82 | /* Common ops */ |
83 | |
84 | case OP_SCOPE: |
85 | myprec = PREC_PREFIX; |
Value stored to 'myprec' is never read | |
86 | assoc = 0; |
87 | fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream); |
88 | fputs_filtered ("::", stream); |
89 | nargs = longest_to_int (exp->elts[pc + 2].longconst); |
90 | (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1)(((nargs + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
91 | fputs_filtered (&exp->elts[pc + 3].string, stream); |
92 | return; |
93 | |
94 | case OP_LONG: |
95 | (*pos) += 3; |
96 | value_print (value_from_longest (exp->elts[pc + 1].type, |
97 | exp->elts[pc + 2].longconst), |
98 | stream, 0, Val_no_prettyprint); |
99 | return; |
100 | |
101 | case OP_DOUBLE: |
102 | (*pos) += 3; |
103 | value_print (value_from_double (exp->elts[pc + 1].type, |
104 | exp->elts[pc + 2].doubleconst), |
105 | stream, 0, Val_no_prettyprint); |
106 | return; |
107 | |
108 | case OP_VAR_VALUE: |
109 | { |
110 | struct block *b; |
111 | (*pos) += 3; |
112 | b = exp->elts[pc + 1].block; |
113 | if (b != NULL((void*)0) |
114 | && BLOCK_FUNCTION (b)(b)->function != NULL((void*)0) |
115 | && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b))(demangle ? (symbol_natural_name (&((b)->function)-> ginfo)) : ((b)->function)->ginfo.name) != NULL((void*)0)) |
116 | { |
117 | fputs_filtered (SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b))(demangle ? (symbol_natural_name (&((b)->function)-> ginfo)) : ((b)->function)->ginfo.name), stream); |
118 | fputs_filtered ("::", stream); |
119 | } |
120 | fputs_filtered (SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol)(demangle ? (symbol_natural_name (&(exp->elts[pc + 2]. symbol)->ginfo)) : (exp->elts[pc + 2].symbol)->ginfo .name), stream); |
121 | } |
122 | return; |
123 | |
124 | case OP_LAST: |
125 | (*pos) += 2; |
126 | fprintf_filtered (stream, "$%d", |
127 | longest_to_int (exp->elts[pc + 1].longconst)); |
128 | return; |
129 | |
130 | case OP_REGISTER: |
131 | { |
132 | int regnum = longest_to_int (exp->elts[pc + 1].longconst); |
133 | const char *name = user_reg_map_regnum_to_name (current_gdbarch, |
134 | regnum); |
135 | (*pos) += 2; |
136 | fprintf_filtered (stream, "$%s", name); |
137 | return; |
138 | } |
139 | |
140 | case OP_BOOL: |
141 | (*pos) += 2; |
142 | fprintf_filtered (stream, "%s", |
143 | longest_to_int (exp->elts[pc + 1].longconst) |
144 | ? "TRUE" : "FALSE"); |
145 | return; |
146 | |
147 | case OP_INTERNALVAR: |
148 | (*pos) += 2; |
149 | fprintf_filtered (stream, "$%s", |
150 | internalvar_name (exp->elts[pc + 1].internalvar)); |
151 | return; |
152 | |
153 | case OP_FUNCALL: |
154 | (*pos) += 2; |
155 | nargs = longest_to_int (exp->elts[pc + 1].longconst); |
156 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
157 | fputs_filtered (" (", stream); |
158 | for (tem = 0; tem < nargs; tem++) |
159 | { |
160 | if (tem != 0) |
161 | fputs_filtered (", ", stream); |
162 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
163 | } |
164 | fputs_filtered (")", stream); |
165 | return; |
166 | |
167 | case OP_NAME: |
168 | case OP_EXPRSTRING: |
169 | nargs = longest_to_int (exp->elts[pc + 1].longconst); |
170 | (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1)(((nargs + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
171 | fputs_filtered (&exp->elts[pc + 2].string, stream); |
172 | return; |
173 | |
174 | case OP_STRING: |
175 | nargs = longest_to_int (exp->elts[pc + 1].longconst); |
176 | (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1)(((nargs + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
177 | /* LA_PRINT_STRING will print using the current repeat count threshold. |
178 | If necessary, we can temporarily set it to zero, or pass it as an |
179 | additional parameter to LA_PRINT_STRING. -fnf */ |
180 | LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0)(current_language->la_printstr(stream, &exp->elts[pc + 2].string, nargs, 1, 0)); |
181 | return; |
182 | |
183 | case OP_BITSTRING: |
184 | nargs = longest_to_int (exp->elts[pc + 1].longconst); |
185 | (*pos) |
186 | += 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT)((((nargs + 8 - 1) / 8) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
187 | fprintf_unfiltered (stream, "B'<unimplemented>'"); |
188 | return; |
189 | |
190 | case OP_OBJC_NSSTRING: /* Objective-C Foundation Class NSString constant. */ |
191 | nargs = longest_to_int (exp->elts[pc + 1].longconst); |
192 | (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1)(((nargs + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
193 | fputs_filtered ("@\"", stream); |
194 | LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0)(current_language->la_printstr(stream, &exp->elts[pc + 2].string, nargs, 1, 0)); |
195 | fputs_filtered ("\"", stream); |
196 | return; |
197 | |
198 | case OP_OBJC_MSGCALL: |
199 | { /* Objective C message (method) call. */ |
200 | char *selector; |
201 | (*pos) += 3; |
202 | nargs = longest_to_int (exp->elts[pc + 2].longconst); |
203 | fprintf_unfiltered (stream, "["); |
204 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
205 | if (0 == target_read_string (exp->elts[pc + 1].longconst, |
206 | &selector, 1024, NULL((void*)0))) |
207 | { |
208 | error ("bad selector"); |
209 | return; |
210 | } |
211 | if (nargs) |
212 | { |
213 | char *s, *nextS; |
214 | s = alloca (strlen (selector) + 1)__builtin_alloca(strlen (selector) + 1); |
215 | strcpy (s, selector); |
216 | for (tem = 0; tem < nargs; tem++) |
217 | { |
218 | nextS = strchr (s, ':'); |
219 | *nextS = '\0'; |
220 | fprintf_unfiltered (stream, " %s: ", s); |
221 | s = nextS + 1; |
222 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
223 | } |
224 | } |
225 | else |
226 | { |
227 | fprintf_unfiltered (stream, " %s", selector); |
228 | } |
229 | fprintf_unfiltered (stream, "]"); |
230 | /* "selector" was malloc'd by target_read_string. Free it. */ |
231 | xfree (selector); |
232 | return; |
233 | } |
234 | |
235 | case OP_ARRAY: |
236 | (*pos) += 3; |
237 | nargs = longest_to_int (exp->elts[pc + 2].longconst); |
238 | nargs -= longest_to_int (exp->elts[pc + 1].longconst); |
239 | nargs++; |
240 | tem = 0; |
241 | if (exp->elts[pc + 4].opcode == OP_LONG |
242 | && exp->elts[pc + 5].type == builtin_type_char |
243 | && exp->language_defn->la_language == language_c) |
244 | { |
245 | /* Attempt to print C character arrays using string syntax. |
246 | Walk through the args, picking up one character from each |
247 | of the OP_LONG expression elements. If any array element |
248 | does not match our expection of what we should find for |
249 | a simple string, revert back to array printing. Note that |
250 | the last expression element is an explicit null terminator |
251 | byte, which doesn't get printed. */ |
252 | tempstr = alloca (nargs)__builtin_alloca(nargs); |
253 | pc += 4; |
254 | while (tem < nargs) |
255 | { |
256 | if (exp->elts[pc].opcode != OP_LONG |
257 | || exp->elts[pc + 1].type != builtin_type_char) |
258 | { |
259 | /* Not a simple array of char, use regular array printing. */ |
260 | tem = 0; |
261 | break; |
262 | } |
263 | else |
264 | { |
265 | tempstr[tem++] = |
266 | longest_to_int (exp->elts[pc + 2].longconst); |
267 | pc += 4; |
268 | } |
269 | } |
270 | } |
271 | if (tem > 0) |
272 | { |
273 | LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0)(current_language->la_printstr(stream, tempstr, nargs - 1, 1, 0)); |
274 | (*pos) = pc; |
275 | } |
276 | else |
277 | { |
278 | fputs_filtered (" {", stream); |
279 | for (tem = 0; tem < nargs; tem++) |
280 | { |
281 | if (tem != 0) |
282 | { |
283 | fputs_filtered (", ", stream); |
284 | } |
285 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
286 | } |
287 | fputs_filtered ("}", stream); |
288 | } |
289 | return; |
290 | |
291 | case OP_LABELED: |
292 | tem = longest_to_int (exp->elts[pc + 1].longconst); |
293 | (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1)(((tem + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
294 | /* Gcc support both these syntaxes. Unsure which is preferred. */ |
295 | #if 1 |
296 | fputs_filtered (&exp->elts[pc + 2].string, stream); |
297 | fputs_filtered (": ", stream); |
298 | #else |
299 | fputs_filtered (".", stream); |
300 | fputs_filtered (&exp->elts[pc + 2].string, stream); |
301 | fputs_filtered ("=", stream); |
302 | #endif |
303 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
304 | return; |
305 | |
306 | case TERNOP_COND: |
307 | if ((int) prec > (int) PREC_COMMA) |
308 | fputs_filtered ("(", stream); |
309 | /* Print the subexpressions, forcing parentheses |
310 | around any binary operations within them. |
311 | This is more parentheses than are strictly necessary, |
312 | but it looks clearer. */ |
313 | print_subexp (exp, pos, stream, PREC_HYPER); |
314 | fputs_filtered (" ? ", stream); |
315 | print_subexp (exp, pos, stream, PREC_HYPER); |
316 | fputs_filtered (" : ", stream); |
317 | print_subexp (exp, pos, stream, PREC_HYPER); |
318 | if ((int) prec > (int) PREC_COMMA) |
319 | fputs_filtered (")", stream); |
320 | return; |
321 | |
322 | case TERNOP_SLICE: |
323 | case TERNOP_SLICE_COUNT: |
324 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
325 | fputs_filtered ("(", stream); |
326 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
327 | fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream); |
328 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
329 | fputs_filtered (")", stream); |
330 | return; |
331 | |
332 | case STRUCTOP_STRUCT: |
333 | tem = longest_to_int (exp->elts[pc + 1].longconst); |
334 | (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1)(((tem + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
335 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
336 | fputs_filtered (".", stream); |
337 | fputs_filtered (&exp->elts[pc + 2].string, stream); |
338 | return; |
339 | |
340 | /* Will not occur for Modula-2 */ |
341 | case STRUCTOP_PTR: |
342 | tem = longest_to_int (exp->elts[pc + 1].longconst); |
343 | (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1)(((tem + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
344 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
345 | fputs_filtered ("->", stream); |
346 | fputs_filtered (&exp->elts[pc + 2].string, stream); |
347 | return; |
348 | |
349 | case BINOP_SUBSCRIPT: |
350 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
351 | fputs_filtered ("[", stream); |
352 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
353 | fputs_filtered ("]", stream); |
354 | return; |
355 | |
356 | case UNOP_POSTINCREMENT: |
357 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
358 | fputs_filtered ("++", stream); |
359 | return; |
360 | |
361 | case UNOP_POSTDECREMENT: |
362 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
363 | fputs_filtered ("--", stream); |
364 | return; |
365 | |
366 | case UNOP_CAST: |
367 | (*pos) += 2; |
368 | if ((int) prec > (int) PREC_PREFIX) |
369 | fputs_filtered ("(", stream); |
370 | fputs_filtered ("(", stream); |
371 | type_print (exp->elts[pc + 1].type, "", stream, 0); |
372 | fputs_filtered (") ", stream); |
373 | print_subexp (exp, pos, stream, PREC_PREFIX); |
374 | if ((int) prec > (int) PREC_PREFIX) |
375 | fputs_filtered (")", stream); |
376 | return; |
377 | |
378 | case UNOP_MEMVAL: |
379 | (*pos) += 2; |
380 | if ((int) prec > (int) PREC_PREFIX) |
381 | fputs_filtered ("(", stream); |
382 | if (TYPE_CODE (exp->elts[pc + 1].type)(exp->elts[pc + 1].type)->main_type->code == TYPE_CODE_FUNC && |
383 | exp->elts[pc + 3].opcode == OP_LONG) |
384 | { |
385 | /* We have a minimal symbol fn, probably. It's encoded |
386 | as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address). |
387 | Swallow the OP_LONG (including both its opcodes); ignore |
388 | its type; print the value in the type of the MEMVAL. */ |
389 | (*pos) += 4; |
390 | val = value_at_lazy (exp->elts[pc + 1].type, |
391 | (CORE_ADDR) exp->elts[pc + 5].longconst, |
392 | NULL((void*)0)); |
393 | value_print (val, stream, 0, Val_no_prettyprint); |
394 | } |
395 | else |
396 | { |
397 | fputs_filtered ("{", stream); |
398 | type_print (exp->elts[pc + 1].type, "", stream, 0); |
399 | fputs_filtered ("} ", stream); |
400 | print_subexp (exp, pos, stream, PREC_PREFIX); |
401 | } |
402 | if ((int) prec > (int) PREC_PREFIX) |
403 | fputs_filtered (")", stream); |
404 | return; |
405 | |
406 | case BINOP_ASSIGN_MODIFY: |
407 | opcode = exp->elts[pc + 1].opcode; |
408 | (*pos) += 2; |
409 | myprec = PREC_ASSIGN; |
410 | assoc = 1; |
411 | assign_modify = 1; |
412 | op_str = "???"; |
413 | for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) |
414 | if (op_print_tab[tem].opcode == opcode) |
415 | { |
416 | op_str = op_print_tab[tem].string; |
417 | break; |
418 | } |
419 | if (op_print_tab[tem].opcode != opcode) |
420 | /* Not found; don't try to keep going because we don't know how |
421 | to interpret further elements. */ |
422 | error ("Invalid expression"); |
423 | break; |
424 | |
425 | /* C++ ops */ |
426 | |
427 | case OP_THIS: |
428 | ++(*pos); |
429 | fputs_filtered ("this", stream); |
430 | return; |
431 | |
432 | /* Objective-C ops */ |
433 | |
434 | case OP_OBJC_SELF: |
435 | ++(*pos); |
436 | fputs_filtered ("self", stream); /* The ObjC equivalent of "this". */ |
437 | return; |
438 | |
439 | /* Modula-2 ops */ |
440 | |
441 | case MULTI_SUBSCRIPT: |
442 | (*pos) += 2; |
443 | nargs = longest_to_int (exp->elts[pc + 1].longconst); |
444 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
445 | fprintf_unfiltered (stream, " ["); |
446 | for (tem = 0; tem < nargs; tem++) |
447 | { |
448 | if (tem != 0) |
449 | fprintf_unfiltered (stream, ", "); |
450 | print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); |
451 | } |
452 | fprintf_unfiltered (stream, "]"); |
453 | return; |
454 | |
455 | case BINOP_VAL: |
456 | (*pos) += 2; |
457 | fprintf_unfiltered (stream, "VAL("); |
458 | type_print (exp->elts[pc + 1].type, "", stream, 0); |
459 | fprintf_unfiltered (stream, ","); |
460 | print_subexp (exp, pos, stream, PREC_PREFIX); |
461 | fprintf_unfiltered (stream, ")"); |
462 | return; |
463 | |
464 | case BINOP_INCL: |
465 | case BINOP_EXCL: |
466 | error ("print_subexp: Not implemented."); |
467 | |
468 | /* Default ops */ |
469 | |
470 | default: |
471 | op_str = "???"; |
472 | for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) |
473 | if (op_print_tab[tem].opcode == opcode) |
474 | { |
475 | op_str = op_print_tab[tem].string; |
476 | myprec = op_print_tab[tem].precedence; |
477 | assoc = op_print_tab[tem].right_assoc; |
478 | break; |
479 | } |
480 | if (op_print_tab[tem].opcode != opcode) |
481 | /* Not found; don't try to keep going because we don't know how |
482 | to interpret further elements. For example, this happens |
483 | if opcode is OP_TYPE. */ |
484 | error ("Invalid expression"); |
485 | } |
486 | |
487 | /* Note that PREC_BUILTIN will always emit parentheses. */ |
488 | if ((int) myprec < (int) prec) |
489 | fputs_filtered ("(", stream); |
490 | if ((int) opcode > (int) BINOP_END) |
491 | { |
492 | if (assoc) |
493 | { |
494 | /* Unary postfix operator. */ |
495 | print_subexp (exp, pos, stream, PREC_SUFFIX); |
496 | fputs_filtered (op_str, stream); |
497 | } |
498 | else |
499 | { |
500 | /* Unary prefix operator. */ |
501 | fputs_filtered (op_str, stream); |
502 | if (myprec == PREC_BUILTIN_FUNCTION) |
503 | fputs_filtered ("(", stream); |
504 | print_subexp (exp, pos, stream, PREC_PREFIX); |
505 | if (myprec == PREC_BUILTIN_FUNCTION) |
506 | fputs_filtered (")", stream); |
507 | } |
508 | } |
509 | else |
510 | { |
511 | /* Binary operator. */ |
512 | /* Print left operand. |
513 | If operator is right-associative, |
514 | increment precedence for this operand. */ |
515 | print_subexp (exp, pos, stream, |
516 | (enum precedence) ((int) myprec + assoc)); |
517 | /* Print the operator itself. */ |
518 | if (assign_modify) |
519 | fprintf_filtered (stream, " %s= ", op_str); |
520 | else if (op_str[0] == ',') |
521 | fprintf_filtered (stream, "%s ", op_str); |
522 | else |
523 | fprintf_filtered (stream, " %s ", op_str); |
524 | /* Print right operand. |
525 | If operator is left-associative, |
526 | increment precedence for this operand. */ |
527 | print_subexp (exp, pos, stream, |
528 | (enum precedence) ((int) myprec + !assoc)); |
529 | } |
530 | |
531 | if ((int) myprec < (int) prec) |
532 | fputs_filtered (")", stream); |
533 | } |
534 | |
535 | /* Return the operator corresponding to opcode OP as |
536 | a string. NULL indicates that the opcode was not found in the |
537 | current language table. */ |
538 | char * |
539 | op_string (enum exp_opcode op) |
540 | { |
541 | int tem; |
542 | const struct op_print *op_print_tab; |
543 | |
544 | op_print_tab = current_language->la_op_print_tab; |
545 | for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) |
546 | if (op_print_tab[tem].opcode == op) |
547 | return op_print_tab[tem].string; |
548 | return NULL((void*)0); |
549 | } |
550 | |
551 | /* Support for dumping the raw data from expressions in a human readable |
552 | form. */ |
553 | |
554 | static char *op_name (struct expression *, enum exp_opcode); |
555 | static int dump_subexp_body (struct expression *exp, struct ui_file *, int); |
556 | |
557 | /* Name for OPCODE, when it appears in expression EXP. */ |
558 | |
559 | static char * |
560 | op_name (struct expression *exp, enum exp_opcode opcode) |
561 | { |
562 | return exp->language_defn->la_exp_desc->op_name (opcode); |
563 | } |
564 | |
565 | /* Default name for the standard operator OPCODE (i.e., one defined in |
566 | the definition of enum exp_opcode). */ |
567 | |
568 | char * |
569 | op_name_standard (enum exp_opcode opcode) |
570 | { |
571 | switch (opcode) |
572 | { |
573 | default: |
574 | { |
575 | static char buf[30]; |
576 | |
577 | sprintf (buf, "<unknown %d>", opcode); |
578 | return buf; |
579 | } |
580 | case OP_NULL: |
581 | return "OP_NULL"; |
582 | case BINOP_ADD: |
583 | return "BINOP_ADD"; |
584 | case BINOP_SUB: |
585 | return "BINOP_SUB"; |
586 | case BINOP_MUL: |
587 | return "BINOP_MUL"; |
588 | case BINOP_DIV: |
589 | return "BINOP_DIV"; |
590 | case BINOP_REM: |
591 | return "BINOP_REM"; |
592 | case BINOP_MOD: |
593 | return "BINOP_MOD"; |
594 | case BINOP_LSH: |
595 | return "BINOP_LSH"; |
596 | case BINOP_RSH: |
597 | return "BINOP_RSH"; |
598 | case BINOP_LOGICAL_AND: |
599 | return "BINOP_LOGICAL_AND"; |
600 | case BINOP_LOGICAL_OR: |
601 | return "BINOP_LOGICAL_OR"; |
602 | case BINOP_BITWISE_AND: |
603 | return "BINOP_BITWISE_AND"; |
604 | case BINOP_BITWISE_IOR: |
605 | return "BINOP_BITWISE_IOR"; |
606 | case BINOP_BITWISE_XOR: |
607 | return "BINOP_BITWISE_XOR"; |
608 | case BINOP_EQUAL: |
609 | return "BINOP_EQUAL"; |
610 | case BINOP_NOTEQUAL: |
611 | return "BINOP_NOTEQUAL"; |
612 | case BINOP_LESS: |
613 | return "BINOP_LESS"; |
614 | case BINOP_GTR: |
615 | return "BINOP_GTR"; |
616 | case BINOP_LEQ: |
617 | return "BINOP_LEQ"; |
618 | case BINOP_GEQ: |
619 | return "BINOP_GEQ"; |
620 | case BINOP_REPEAT: |
621 | return "BINOP_REPEAT"; |
622 | case BINOP_ASSIGN: |
623 | return "BINOP_ASSIGN"; |
624 | case BINOP_COMMA: |
625 | return "BINOP_COMMA"; |
626 | case BINOP_SUBSCRIPT: |
627 | return "BINOP_SUBSCRIPT"; |
628 | case MULTI_SUBSCRIPT: |
629 | return "MULTI_SUBSCRIPT"; |
630 | case BINOP_EXP: |
631 | return "BINOP_EXP"; |
632 | case BINOP_MIN: |
633 | return "BINOP_MIN"; |
634 | case BINOP_MAX: |
635 | return "BINOP_MAX"; |
636 | case STRUCTOP_MEMBER: |
637 | return "STRUCTOP_MEMBER"; |
638 | case STRUCTOP_MPTR: |
639 | return "STRUCTOP_MPTR"; |
640 | case BINOP_INTDIV: |
641 | return "BINOP_INTDIV"; |
642 | case BINOP_ASSIGN_MODIFY: |
643 | return "BINOP_ASSIGN_MODIFY"; |
644 | case BINOP_VAL: |
645 | return "BINOP_VAL"; |
646 | case BINOP_INCL: |
647 | return "BINOP_INCL"; |
648 | case BINOP_EXCL: |
649 | return "BINOP_EXCL"; |
650 | case BINOP_CONCAT: |
651 | return "BINOP_CONCAT"; |
652 | case BINOP_RANGE: |
653 | return "BINOP_RANGE"; |
654 | case BINOP_END: |
655 | return "BINOP_END"; |
656 | case TERNOP_COND: |
657 | return "TERNOP_COND"; |
658 | case TERNOP_SLICE: |
659 | return "TERNOP_SLICE"; |
660 | case TERNOP_SLICE_COUNT: |
661 | return "TERNOP_SLICE_COUNT"; |
662 | case OP_LONG: |
663 | return "OP_LONG"; |
664 | case OP_DOUBLE: |
665 | return "OP_DOUBLE"; |
666 | case OP_VAR_VALUE: |
667 | return "OP_VAR_VALUE"; |
668 | case OP_LAST: |
669 | return "OP_LAST"; |
670 | case OP_REGISTER: |
671 | return "OP_REGISTER"; |
672 | case OP_INTERNALVAR: |
673 | return "OP_INTERNALVAR"; |
674 | case OP_FUNCALL: |
675 | return "OP_FUNCALL"; |
676 | case OP_STRING: |
677 | return "OP_STRING"; |
678 | case OP_BITSTRING: |
679 | return "OP_BITSTRING"; |
680 | case OP_ARRAY: |
681 | return "OP_ARRAY"; |
682 | case UNOP_CAST: |
683 | return "UNOP_CAST"; |
684 | case UNOP_MEMVAL: |
685 | return "UNOP_MEMVAL"; |
686 | case UNOP_NEG: |
687 | return "UNOP_NEG"; |
688 | case UNOP_LOGICAL_NOT: |
689 | return "UNOP_LOGICAL_NOT"; |
690 | case UNOP_COMPLEMENT: |
691 | return "UNOP_COMPLEMENT"; |
692 | case UNOP_IND: |
693 | return "UNOP_IND"; |
694 | case UNOP_ADDR: |
695 | return "UNOP_ADDR"; |
696 | case UNOP_PREINCREMENT: |
697 | return "UNOP_PREINCREMENT"; |
698 | case UNOP_POSTINCREMENT: |
699 | return "UNOP_POSTINCREMENT"; |
700 | case UNOP_PREDECREMENT: |
701 | return "UNOP_PREDECREMENT"; |
702 | case UNOP_POSTDECREMENT: |
703 | return "UNOP_POSTDECREMENT"; |
704 | case UNOP_SIZEOF: |
705 | return "UNOP_SIZEOF"; |
706 | case UNOP_LOWER: |
707 | return "UNOP_LOWER"; |
708 | case UNOP_UPPER: |
709 | return "UNOP_UPPER"; |
710 | case UNOP_LENGTH: |
711 | return "UNOP_LENGTH"; |
712 | case UNOP_PLUS: |
713 | return "UNOP_PLUS"; |
714 | case UNOP_CAP: |
715 | return "UNOP_CAP"; |
716 | case UNOP_CHR: |
717 | return "UNOP_CHR"; |
718 | case UNOP_ORD: |
719 | return "UNOP_ORD"; |
720 | case UNOP_ABS: |
721 | return "UNOP_ABS"; |
722 | case UNOP_FLOAT: |
723 | return "UNOP_FLOAT"; |
724 | case UNOP_HIGH: |
725 | return "UNOP_HIGH"; |
726 | case UNOP_MAX: |
727 | return "UNOP_MAX"; |
728 | case UNOP_MIN: |
729 | return "UNOP_MIN"; |
730 | case UNOP_ODD: |
731 | return "UNOP_ODD"; |
732 | case UNOP_TRUNC: |
733 | return "UNOP_TRUNC"; |
734 | case OP_BOOL: |
735 | return "OP_BOOL"; |
736 | case OP_M2_STRING: |
737 | return "OP_M2_STRING"; |
738 | case STRUCTOP_STRUCT: |
739 | return "STRUCTOP_STRUCT"; |
740 | case STRUCTOP_PTR: |
741 | return "STRUCTOP_PTR"; |
742 | case OP_THIS: |
743 | return "OP_THIS"; |
744 | case OP_OBJC_SELF: |
745 | return "OP_OBJC_SELF"; |
746 | case OP_SCOPE: |
747 | return "OP_SCOPE"; |
748 | case OP_TYPE: |
749 | return "OP_TYPE"; |
750 | case OP_LABELED: |
751 | return "OP_LABELED"; |
752 | } |
753 | } |
754 | |
755 | void |
756 | dump_raw_expression (struct expression *exp, struct ui_file *stream, |
757 | char *note) |
758 | { |
759 | int elt; |
760 | char *opcode_name; |
761 | char *eltscan; |
762 | int eltsize; |
763 | |
764 | fprintf_filtered (stream, "Dump of expression @ "); |
765 | gdb_print_host_address (exp, stream); |
766 | fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n", |
767 | exp->language_defn->la_name, exp->nelts, |
768 | (long) sizeof (union exp_element)); |
769 | fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode", |
770 | "Hex Value", "String Value"); |
771 | for (elt = 0; elt < exp->nelts; elt++) |
772 | { |
773 | fprintf_filtered (stream, "\t%5d ", elt); |
774 | opcode_name = op_name (exp, exp->elts[elt].opcode); |
775 | |
776 | fprintf_filtered (stream, "%20s ", opcode_name); |
777 | print_longest (stream, 'd', 0, exp->elts[elt].longconst); |
778 | fprintf_filtered (stream, " "); |
779 | |
780 | for (eltscan = (char *) &exp->elts[elt], |
781 | eltsize = sizeof (union exp_element); |
782 | eltsize-- > 0; |
783 | eltscan++) |
784 | { |
785 | fprintf_filtered (stream, "%c", |
786 | isprint (*eltscan) ? (*eltscan & 0xFF) : '.'); |
787 | } |
788 | fprintf_filtered (stream, "\n"); |
789 | } |
790 | } |
791 | |
792 | /* Dump the subexpression of prefix expression EXP whose operator is at |
793 | position ELT onto STREAM. Returns the position of the next |
794 | subexpression in EXP. */ |
795 | |
796 | int |
797 | dump_subexp (struct expression *exp, struct ui_file *stream, int elt) |
798 | { |
799 | static int indent = 0; |
800 | int i; |
801 | |
802 | fprintf_filtered (stream, "\n"); |
803 | fprintf_filtered (stream, "\t%5d ", elt); |
804 | |
805 | for (i = 1; i <= indent; i++) |
806 | fprintf_filtered (stream, " "); |
807 | indent += 2; |
808 | |
809 | fprintf_filtered (stream, "%-20s ", op_name (exp, exp->elts[elt].opcode)); |
810 | |
811 | elt = dump_subexp_body (exp, stream, elt); |
812 | |
813 | indent -= 2; |
814 | |
815 | return elt; |
816 | } |
817 | |
818 | /* Dump the operands of prefix expression EXP whose opcode is at |
819 | position ELT onto STREAM. Returns the position of the next |
820 | subexpression in EXP. */ |
821 | |
822 | static int |
823 | dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt) |
824 | { |
825 | return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt); |
826 | } |
827 | |
828 | /* Default value for subexp_body in exp_descriptor vector. */ |
829 | |
830 | int |
831 | dump_subexp_body_standard (struct expression *exp, |
832 | struct ui_file *stream, int elt) |
833 | { |
834 | int opcode = exp->elts[elt++].opcode; |
835 | |
836 | switch (opcode) |
837 | { |
838 | case TERNOP_COND: |
839 | case TERNOP_SLICE: |
840 | case TERNOP_SLICE_COUNT: |
841 | elt = dump_subexp (exp, stream, elt); |
842 | case BINOP_ADD: |
843 | case BINOP_SUB: |
844 | case BINOP_MUL: |
845 | case BINOP_DIV: |
846 | case BINOP_REM: |
847 | case BINOP_MOD: |
848 | case BINOP_LSH: |
849 | case BINOP_RSH: |
850 | case BINOP_LOGICAL_AND: |
851 | case BINOP_LOGICAL_OR: |
852 | case BINOP_BITWISE_AND: |
853 | case BINOP_BITWISE_IOR: |
854 | case BINOP_BITWISE_XOR: |
855 | case BINOP_EQUAL: |
856 | case BINOP_NOTEQUAL: |
857 | case BINOP_LESS: |
858 | case BINOP_GTR: |
859 | case BINOP_LEQ: |
860 | case BINOP_GEQ: |
861 | case BINOP_REPEAT: |
862 | case BINOP_ASSIGN: |
863 | case BINOP_COMMA: |
864 | case BINOP_SUBSCRIPT: |
865 | case BINOP_EXP: |
866 | case BINOP_MIN: |
867 | case BINOP_MAX: |
868 | case BINOP_INTDIV: |
869 | case BINOP_ASSIGN_MODIFY: |
870 | case BINOP_VAL: |
871 | case BINOP_INCL: |
872 | case BINOP_EXCL: |
873 | case BINOP_CONCAT: |
874 | case BINOP_IN: |
875 | case BINOP_RANGE: |
876 | case BINOP_END: |
877 | elt = dump_subexp (exp, stream, elt); |
878 | case UNOP_NEG: |
879 | case UNOP_LOGICAL_NOT: |
880 | case UNOP_COMPLEMENT: |
881 | case UNOP_IND: |
882 | case UNOP_ADDR: |
883 | case UNOP_PREINCREMENT: |
884 | case UNOP_POSTINCREMENT: |
885 | case UNOP_PREDECREMENT: |
886 | case UNOP_POSTDECREMENT: |
887 | case UNOP_SIZEOF: |
888 | case UNOP_PLUS: |
889 | case UNOP_CAP: |
890 | case UNOP_CHR: |
891 | case UNOP_ORD: |
892 | case UNOP_ABS: |
893 | case UNOP_FLOAT: |
894 | case UNOP_HIGH: |
895 | case UNOP_MAX: |
896 | case UNOP_MIN: |
897 | case UNOP_ODD: |
898 | case UNOP_TRUNC: |
899 | case UNOP_LOWER: |
900 | case UNOP_UPPER: |
901 | case UNOP_LENGTH: |
902 | case UNOP_CARD: |
903 | case UNOP_CHMAX: |
904 | case UNOP_CHMIN: |
905 | elt = dump_subexp (exp, stream, elt); |
906 | break; |
907 | case OP_LONG: |
908 | fprintf_filtered (stream, "Type @"); |
909 | gdb_print_host_address (exp->elts[elt].type, stream); |
910 | fprintf_filtered (stream, " ("); |
911 | type_print (exp->elts[elt].type, NULL((void*)0), stream, 0); |
912 | fprintf_filtered (stream, "), value %ld (0x%lx)", |
913 | (long) exp->elts[elt + 1].longconst, |
914 | (long) exp->elts[elt + 1].longconst); |
915 | elt += 3; |
916 | break; |
917 | case OP_DOUBLE: |
918 | fprintf_filtered (stream, "Type @"); |
919 | gdb_print_host_address (exp->elts[elt].type, stream); |
920 | fprintf_filtered (stream, " ("); |
921 | type_print (exp->elts[elt].type, NULL((void*)0), stream, 0); |
922 | fprintf_filtered (stream, "), value %g", |
923 | (double) exp->elts[elt + 1].doubleconst); |
924 | elt += 3; |
925 | break; |
926 | case OP_VAR_VALUE: |
927 | fprintf_filtered (stream, "Block @"); |
928 | gdb_print_host_address (exp->elts[elt].block, stream); |
929 | fprintf_filtered (stream, ", symbol @"); |
930 | gdb_print_host_address (exp->elts[elt + 1].symbol, stream); |
931 | fprintf_filtered (stream, " (%s)", |
932 | DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol)(exp->elts[elt + 1].symbol)->ginfo.name); |
933 | elt += 3; |
934 | break; |
935 | case OP_LAST: |
936 | fprintf_filtered (stream, "History element %ld", |
937 | (long) exp->elts[elt].longconst); |
938 | elt += 2; |
939 | break; |
940 | case OP_REGISTER: |
941 | fprintf_filtered (stream, "Register %ld", |
942 | (long) exp->elts[elt].longconst); |
943 | elt += 2; |
944 | break; |
945 | case OP_INTERNALVAR: |
946 | fprintf_filtered (stream, "Internal var @"); |
947 | gdb_print_host_address (exp->elts[elt].internalvar, stream); |
948 | fprintf_filtered (stream, " (%s)", |
949 | exp->elts[elt].internalvar->name); |
950 | elt += 2; |
951 | break; |
952 | case OP_FUNCALL: |
953 | { |
954 | int i, nargs; |
955 | |
956 | nargs = longest_to_int (exp->elts[elt].longconst); |
957 | |
958 | fprintf_filtered (stream, "Number of args: %d", nargs); |
959 | elt += 2; |
960 | |
961 | for (i = 1; i <= nargs + 1; i++) |
962 | elt = dump_subexp (exp, stream, elt); |
963 | } |
964 | break; |
965 | case OP_ARRAY: |
966 | { |
967 | int lower, upper; |
968 | int i; |
969 | |
970 | lower = longest_to_int (exp->elts[elt].longconst); |
971 | upper = longest_to_int (exp->elts[elt + 1].longconst); |
972 | |
973 | fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper); |
974 | elt += 3; |
975 | |
976 | for (i = 1; i <= upper - lower + 1; i++) |
977 | elt = dump_subexp (exp, stream, elt); |
978 | } |
979 | break; |
980 | case UNOP_MEMVAL: |
981 | case UNOP_CAST: |
982 | fprintf_filtered (stream, "Type @"); |
983 | gdb_print_host_address (exp->elts[elt].type, stream); |
984 | fprintf_filtered (stream, " ("); |
985 | type_print (exp->elts[elt].type, NULL((void*)0), stream, 0); |
986 | fprintf_filtered (stream, ")"); |
987 | elt = dump_subexp (exp, stream, elt + 2); |
988 | break; |
989 | case OP_TYPE: |
990 | fprintf_filtered (stream, "Type @"); |
991 | gdb_print_host_address (exp->elts[elt].type, stream); |
992 | fprintf_filtered (stream, " ("); |
993 | type_print (exp->elts[elt].type, NULL((void*)0), stream, 0); |
994 | fprintf_filtered (stream, ")"); |
995 | elt += 2; |
996 | break; |
997 | case STRUCTOP_STRUCT: |
998 | case STRUCTOP_PTR: |
999 | { |
1000 | char *elem_name; |
1001 | int len; |
1002 | |
1003 | len = longest_to_int (exp->elts[elt].longconst); |
1004 | elem_name = &exp->elts[elt + 1].string; |
1005 | |
1006 | fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name); |
1007 | elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1)(((len + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element))); |
1008 | } |
1009 | break; |
1010 | case OP_SCOPE: |
1011 | { |
1012 | char *elem_name; |
1013 | int len; |
1014 | |
1015 | fprintf_filtered (stream, "Type @"); |
1016 | gdb_print_host_address (exp->elts[elt].type, stream); |
1017 | fprintf_filtered (stream, " ("); |
1018 | type_print (exp->elts[elt].type, NULL((void*)0), stream, 0); |
1019 | fprintf_filtered (stream, ") "); |
1020 | |
1021 | len = longest_to_int (exp->elts[elt + 1].longconst); |
1022 | elem_name = &exp->elts[elt + 2].string; |
1023 | |
1024 | fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name); |
1025 | elt += 4 + BYTES_TO_EXP_ELEM (len + 1)(((len + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element)); |
1026 | } |
1027 | break; |
1028 | default: |
1029 | case OP_NULL: |
1030 | case STRUCTOP_MEMBER: |
1031 | case STRUCTOP_MPTR: |
1032 | case MULTI_SUBSCRIPT: |
1033 | case OP_F77_UNDETERMINED_ARGLIST: |
1034 | case OP_COMPLEX: |
1035 | case OP_STRING: |
1036 | case OP_BITSTRING: |
1037 | case OP_BOOL: |
1038 | case OP_M2_STRING: |
1039 | case OP_THIS: |
1040 | case OP_LABELED: |
1041 | case OP_NAME: |
1042 | case OP_EXPRSTRING: |
1043 | fprintf_filtered (stream, "Unknown format"); |
1044 | } |
1045 | |
1046 | return elt; |
1047 | } |
1048 | |
1049 | void |
1050 | dump_prefix_expression (struct expression *exp, struct ui_file *stream) |
1051 | { |
1052 | int elt; |
1053 | |
1054 | fprintf_filtered (stream, "Dump of expression @ "); |
1055 | gdb_print_host_address (exp, stream); |
1056 | fputs_filtered (", after conversion to prefix form:\nExpression: `", stream); |
1057 | if (exp->elts[0].opcode != OP_TYPE) |
1058 | print_expression (exp, stream); |
1059 | else |
1060 | fputs_filtered ("Type printing not yet supported....", stream); |
1061 | fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n", |
1062 | exp->language_defn->la_name, exp->nelts, |
1063 | (long) sizeof (union exp_element)); |
1064 | fputs_filtered ("\n", stream); |
1065 | |
1066 | for (elt = 0; elt < exp->nelts;) |
1067 | elt = dump_subexp (exp, stream, elt); |
1068 | fputs_filtered ("\n", stream); |
1069 | } |