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