xref: /openbsd/gnu/usr.bin/binutils/gdb/expprint.c (revision b725ae77)
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