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