119370Spst/* Print in infix form a struct expression.
2130803Smarcel
398944Sobrien   Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
4130803Smarcel   1998, 1999, 2000, 2003 Free Software Foundation, Inc.
519370Spst
698944Sobrien   This file is part of GDB.
719370Spst
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1219370Spst
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1719370Spst
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2219370Spst
2319370Spst#include "defs.h"
2419370Spst#include "symtab.h"
2519370Spst#include "gdbtypes.h"
2619370Spst#include "expression.h"
2719370Spst#include "value.h"
2819370Spst#include "language.h"
2919370Spst#include "parser-defs.h"
30130803Smarcel#include "user-regs.h"		/* For user_reg_map_regnum_to_name.  */
31130803Smarcel#include "target.h"
32130803Smarcel#include "gdb_string.h"
33130803Smarcel#include "block.h"
3419370Spst
3546283Sdfr#ifdef HAVE_CTYPE_H
3646283Sdfr#include <ctype.h>
3746283Sdfr#endif
3846283Sdfr
3919370Spstvoid
4098944Sobrienprint_expression (struct expression *exp, struct ui_file *stream)
4119370Spst{
4219370Spst  int pc = 0;
4319370Spst  print_subexp (exp, &pc, stream, PREC_NULL);
4419370Spst}
4519370Spst
4619370Spst/* Print the subexpression of EXP that starts in position POS, on STREAM.
4719370Spst   PREC is the precedence of the surrounding operator;
4819370Spst   if the precedence of the main operator of this subexpression is less,
4919370Spst   parentheses are needed here.  */
5019370Spst
51130803Smarcelvoid
52130803Smarcelprint_subexp (struct expression *exp, int *pos,
5398944Sobrien	      struct ui_file *stream, enum precedence prec)
5419370Spst{
55130803Smarcel  exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec);
56130803Smarcel}
57130803Smarcel
58130803Smarcel/* Standard implementation of print_subexp for use in language_defn
59130803Smarcel   vectors.  */
60130803Smarcelvoid
61130803Smarcelprint_subexp_standard (struct expression *exp, int *pos,
62130803Smarcel		       struct ui_file *stream, enum precedence prec)
63130803Smarcel{
64130803Smarcel  unsigned tem;
65130803Smarcel  const struct op_print *op_print_tab;
66130803Smarcel  int pc;
6719370Spst  unsigned nargs;
68130803Smarcel  char *op_str;
6919370Spst  int assign_modify = 0;
7019370Spst  enum exp_opcode opcode;
7119370Spst  enum precedence myprec = PREC_NULL;
7219370Spst  /* Set to 1 for a right-associative operator.  */
7319370Spst  int assoc = 0;
7498944Sobrien  struct value *val;
7519370Spst  char *tempstr = NULL;
7619370Spst
7719370Spst  op_print_tab = exp->language_defn->la_op_print_tab;
7819370Spst  pc = (*pos)++;
7919370Spst  opcode = exp->elts[pc].opcode;
8019370Spst  switch (opcode)
8119370Spst    {
8298944Sobrien      /* Common ops */
8319370Spst
8419370Spst    case OP_SCOPE:
8519370Spst      myprec = PREC_PREFIX;
8619370Spst      assoc = 0;
8719370Spst      fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream);
8819370Spst      fputs_filtered ("::", stream);
8919370Spst      nargs = longest_to_int (exp->elts[pc + 2].longconst);
9019370Spst      (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1);
9119370Spst      fputs_filtered (&exp->elts[pc + 3].string, stream);
9219370Spst      return;
9319370Spst
9419370Spst    case OP_LONG:
9519370Spst      (*pos) += 3;
9619370Spst      value_print (value_from_longest (exp->elts[pc + 1].type,
9719370Spst				       exp->elts[pc + 2].longconst),
9819370Spst		   stream, 0, Val_no_prettyprint);
9919370Spst      return;
10019370Spst
10119370Spst    case OP_DOUBLE:
10219370Spst      (*pos) += 3;
10319370Spst      value_print (value_from_double (exp->elts[pc + 1].type,
10419370Spst				      exp->elts[pc + 2].doubleconst),
10519370Spst		   stream, 0, Val_no_prettyprint);
10619370Spst      return;
10719370Spst
10819370Spst    case OP_VAR_VALUE:
10919370Spst      {
11019370Spst	struct block *b;
11119370Spst	(*pos) += 3;
11219370Spst	b = exp->elts[pc + 1].block;
11319370Spst	if (b != NULL
11419370Spst	    && BLOCK_FUNCTION (b) != NULL
115130803Smarcel	    && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)) != NULL)
11619370Spst	  {
117130803Smarcel	    fputs_filtered (SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)), stream);
11819370Spst	    fputs_filtered ("::", stream);
11919370Spst	  }
120130803Smarcel	fputs_filtered (SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol), stream);
12119370Spst      }
12219370Spst      return;
12319370Spst
12419370Spst    case OP_LAST:
12519370Spst      (*pos) += 2;
12619370Spst      fprintf_filtered (stream, "$%d",
12719370Spst			longest_to_int (exp->elts[pc + 1].longconst));
12819370Spst      return;
12919370Spst
13019370Spst    case OP_REGISTER:
131130803Smarcel      {
132130803Smarcel	int regnum = longest_to_int (exp->elts[pc + 1].longconst);
133130803Smarcel	const char *name = user_reg_map_regnum_to_name (current_gdbarch,
134130803Smarcel							regnum);
135130803Smarcel	(*pos) += 2;
136130803Smarcel	fprintf_filtered (stream, "$%s", name);
137130803Smarcel	return;
138130803Smarcel      }
13919370Spst
14019370Spst    case OP_BOOL:
14119370Spst      (*pos) += 2;
14219370Spst      fprintf_filtered (stream, "%s",
14319370Spst			longest_to_int (exp->elts[pc + 1].longconst)
14419370Spst			? "TRUE" : "FALSE");
14519370Spst      return;
14619370Spst
14719370Spst    case OP_INTERNALVAR:
14819370Spst      (*pos) += 2;
14919370Spst      fprintf_filtered (stream, "$%s",
15098944Sobrien			internalvar_name (exp->elts[pc + 1].internalvar));
15119370Spst      return;
15219370Spst
15319370Spst    case OP_FUNCALL:
15419370Spst      (*pos) += 2;
15519370Spst      nargs = longest_to_int (exp->elts[pc + 1].longconst);
15619370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
15719370Spst      fputs_filtered (" (", stream);
15819370Spst      for (tem = 0; tem < nargs; tem++)
15919370Spst	{
16019370Spst	  if (tem != 0)
16119370Spst	    fputs_filtered (", ", stream);
16219370Spst	  print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
16319370Spst	}
16419370Spst      fputs_filtered (")", stream);
16519370Spst      return;
16619370Spst
16719370Spst    case OP_NAME:
16819370Spst    case OP_EXPRSTRING:
16998944Sobrien      nargs = longest_to_int (exp->elts[pc + 1].longconst);
17019370Spst      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
17119370Spst      fputs_filtered (&exp->elts[pc + 2].string, stream);
17219370Spst      return;
17319370Spst
17419370Spst    case OP_STRING:
17598944Sobrien      nargs = longest_to_int (exp->elts[pc + 1].longconst);
17619370Spst      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
17719370Spst      /* LA_PRINT_STRING will print using the current repeat count threshold.
17898944Sobrien         If necessary, we can temporarily set it to zero, or pass it as an
17998944Sobrien         additional parameter to LA_PRINT_STRING.  -fnf */
18046283Sdfr      LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0);
18119370Spst      return;
18219370Spst
18319370Spst    case OP_BITSTRING:
18498944Sobrien      nargs = longest_to_int (exp->elts[pc + 1].longconst);
18519370Spst      (*pos)
18619370Spst	+= 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
18746283Sdfr      fprintf_unfiltered (stream, "B'<unimplemented>'");
18819370Spst      return;
18919370Spst
190130803Smarcel    case OP_OBJC_NSSTRING:	/* Objective-C Foundation Class NSString constant.  */
191130803Smarcel      nargs = longest_to_int (exp->elts[pc + 1].longconst);
192130803Smarcel      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
193130803Smarcel      fputs_filtered ("@\"", stream);
194130803Smarcel      LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0);
195130803Smarcel      fputs_filtered ("\"", stream);
196130803Smarcel      return;
197130803Smarcel
198130803Smarcel    case OP_OBJC_MSGCALL:
199130803Smarcel      {			/* Objective C message (method) call.  */
200130803Smarcel	char *selector;
201130803Smarcel	(*pos) += 3;
202130803Smarcel	nargs = longest_to_int (exp->elts[pc + 2].longconst);
203130803Smarcel	fprintf_unfiltered (stream, "[");
204130803Smarcel	print_subexp (exp, pos, stream, PREC_SUFFIX);
205130803Smarcel	if (0 == target_read_string (exp->elts[pc + 1].longconst,
206130803Smarcel				     &selector, 1024, NULL))
207130803Smarcel	  {
208130803Smarcel	    error ("bad selector");
209130803Smarcel	    return;
210130803Smarcel	  }
211130803Smarcel	if (nargs)
212130803Smarcel	  {
213130803Smarcel	    char *s, *nextS;
214130803Smarcel	    s = alloca (strlen (selector) + 1);
215130803Smarcel	    strcpy (s, selector);
216130803Smarcel	    for (tem = 0; tem < nargs; tem++)
217130803Smarcel	      {
218130803Smarcel		nextS = strchr (s, ':');
219130803Smarcel		*nextS = '\0';
220130803Smarcel		fprintf_unfiltered (stream, " %s: ", s);
221130803Smarcel		s = nextS + 1;
222130803Smarcel		print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
223130803Smarcel	      }
224130803Smarcel	  }
225130803Smarcel	else
226130803Smarcel	  {
227130803Smarcel	    fprintf_unfiltered (stream, " %s", selector);
228130803Smarcel	  }
229130803Smarcel	fprintf_unfiltered (stream, "]");
230130803Smarcel	/* "selector" was malloc'd by target_read_string. Free it.  */
231130803Smarcel	xfree (selector);
232130803Smarcel	return;
233130803Smarcel      }
234130803Smarcel
23519370Spst    case OP_ARRAY:
23619370Spst      (*pos) += 3;
23719370Spst      nargs = longest_to_int (exp->elts[pc + 2].longconst);
23819370Spst      nargs -= longest_to_int (exp->elts[pc + 1].longconst);
23919370Spst      nargs++;
24019370Spst      tem = 0;
24119370Spst      if (exp->elts[pc + 4].opcode == OP_LONG
24219370Spst	  && exp->elts[pc + 5].type == builtin_type_char
24319370Spst	  && exp->language_defn->la_language == language_c)
24419370Spst	{
24519370Spst	  /* Attempt to print C character arrays using string syntax.
24619370Spst	     Walk through the args, picking up one character from each
24719370Spst	     of the OP_LONG expression elements.  If any array element
24819370Spst	     does not match our expection of what we should find for
24919370Spst	     a simple string, revert back to array printing.  Note that
25019370Spst	     the last expression element is an explicit null terminator
25119370Spst	     byte, which doesn't get printed. */
25219370Spst	  tempstr = alloca (nargs);
25319370Spst	  pc += 4;
25419370Spst	  while (tem < nargs)
25519370Spst	    {
25619370Spst	      if (exp->elts[pc].opcode != OP_LONG
25719370Spst		  || exp->elts[pc + 1].type != builtin_type_char)
25819370Spst		{
25919370Spst		  /* Not a simple array of char, use regular array printing. */
26019370Spst		  tem = 0;
26119370Spst		  break;
26219370Spst		}
26319370Spst	      else
26419370Spst		{
26519370Spst		  tempstr[tem++] =
26619370Spst		    longest_to_int (exp->elts[pc + 2].longconst);
26719370Spst		  pc += 4;
26819370Spst		}
26919370Spst	    }
27019370Spst	}
27119370Spst      if (tem > 0)
27219370Spst	{
27346283Sdfr	  LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0);
27419370Spst	  (*pos) = pc;
27519370Spst	}
27619370Spst      else
27719370Spst	{
278130803Smarcel	  fputs_filtered (" {", stream);
27919370Spst	  for (tem = 0; tem < nargs; tem++)
28019370Spst	    {
28119370Spst	      if (tem != 0)
28219370Spst		{
28319370Spst		  fputs_filtered (", ", stream);
28419370Spst		}
28519370Spst	      print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
28619370Spst	    }
287130803Smarcel	  fputs_filtered ("}", stream);
28819370Spst	}
28919370Spst      return;
29019370Spst
29119370Spst    case OP_LABELED:
29219370Spst      tem = longest_to_int (exp->elts[pc + 1].longconst);
29319370Spst      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
294130803Smarcel      /* Gcc support both these syntaxes.  Unsure which is preferred.  */
29519370Spst#if 1
296130803Smarcel      fputs_filtered (&exp->elts[pc + 2].string, stream);
297130803Smarcel      fputs_filtered (": ", stream);
29819370Spst#else
299130803Smarcel      fputs_filtered (".", stream);
300130803Smarcel      fputs_filtered (&exp->elts[pc + 2].string, stream);
301130803Smarcel      fputs_filtered ("=", stream);
30219370Spst#endif
30319370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
30419370Spst      return;
30519370Spst
30619370Spst    case TERNOP_COND:
30719370Spst      if ((int) prec > (int) PREC_COMMA)
30819370Spst	fputs_filtered ("(", stream);
30919370Spst      /* Print the subexpressions, forcing parentheses
31098944Sobrien         around any binary operations within them.
31198944Sobrien         This is more parentheses than are strictly necessary,
31298944Sobrien         but it looks clearer.  */
31319370Spst      print_subexp (exp, pos, stream, PREC_HYPER);
31419370Spst      fputs_filtered (" ? ", stream);
31519370Spst      print_subexp (exp, pos, stream, PREC_HYPER);
31619370Spst      fputs_filtered (" : ", stream);
31719370Spst      print_subexp (exp, pos, stream, PREC_HYPER);
31819370Spst      if ((int) prec > (int) PREC_COMMA)
31919370Spst	fputs_filtered (")", stream);
32019370Spst      return;
32119370Spst
32219370Spst    case TERNOP_SLICE:
32319370Spst    case TERNOP_SLICE_COUNT:
32419370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
32519370Spst      fputs_filtered ("(", stream);
32619370Spst      print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
32719370Spst      fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream);
32819370Spst      print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
32919370Spst      fputs_filtered (")", stream);
33019370Spst      return;
33119370Spst
33219370Spst    case STRUCTOP_STRUCT:
33319370Spst      tem = longest_to_int (exp->elts[pc + 1].longconst);
33419370Spst      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
33519370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
33619370Spst      fputs_filtered (".", stream);
33719370Spst      fputs_filtered (&exp->elts[pc + 2].string, stream);
33819370Spst      return;
33919370Spst
34098944Sobrien      /* Will not occur for Modula-2 */
34119370Spst    case STRUCTOP_PTR:
34219370Spst      tem = longest_to_int (exp->elts[pc + 1].longconst);
34319370Spst      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
34419370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
34519370Spst      fputs_filtered ("->", stream);
34619370Spst      fputs_filtered (&exp->elts[pc + 2].string, stream);
34719370Spst      return;
34819370Spst
34919370Spst    case BINOP_SUBSCRIPT:
35019370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
35119370Spst      fputs_filtered ("[", stream);
35219370Spst      print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
35319370Spst      fputs_filtered ("]", stream);
35419370Spst      return;
35519370Spst
35619370Spst    case UNOP_POSTINCREMENT:
35719370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
35819370Spst      fputs_filtered ("++", stream);
35919370Spst      return;
36019370Spst
36119370Spst    case UNOP_POSTDECREMENT:
36219370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
36319370Spst      fputs_filtered ("--", stream);
36419370Spst      return;
36519370Spst
36619370Spst    case UNOP_CAST:
36719370Spst      (*pos) += 2;
36819370Spst      if ((int) prec > (int) PREC_PREFIX)
36998944Sobrien	fputs_filtered ("(", stream);
37019370Spst      fputs_filtered ("(", stream);
37119370Spst      type_print (exp->elts[pc + 1].type, "", stream, 0);
37219370Spst      fputs_filtered (") ", stream);
37319370Spst      print_subexp (exp, pos, stream, PREC_PREFIX);
37419370Spst      if ((int) prec > (int) PREC_PREFIX)
37598944Sobrien	fputs_filtered (")", stream);
37619370Spst      return;
37719370Spst
37819370Spst    case UNOP_MEMVAL:
37919370Spst      (*pos) += 2;
38019370Spst      if ((int) prec > (int) PREC_PREFIX)
38198944Sobrien	fputs_filtered ("(", stream);
382130803Smarcel      if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC &&
38398944Sobrien	  exp->elts[pc + 3].opcode == OP_LONG)
38498944Sobrien	{
38598944Sobrien	  /* We have a minimal symbol fn, probably.  It's encoded
38698944Sobrien	     as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
38798944Sobrien	     Swallow the OP_LONG (including both its opcodes); ignore
38898944Sobrien	     its type; print the value in the type of the MEMVAL.  */
38998944Sobrien	  (*pos) += 4;
39098944Sobrien	  val = value_at_lazy (exp->elts[pc + 1].type,
39198944Sobrien			       (CORE_ADDR) exp->elts[pc + 5].longconst,
39298944Sobrien			       NULL);
39398944Sobrien	  value_print (val, stream, 0, Val_no_prettyprint);
39498944Sobrien	}
39598944Sobrien      else
39698944Sobrien	{
39798944Sobrien	  fputs_filtered ("{", stream);
39898944Sobrien	  type_print (exp->elts[pc + 1].type, "", stream, 0);
39998944Sobrien	  fputs_filtered ("} ", stream);
40098944Sobrien	  print_subexp (exp, pos, stream, PREC_PREFIX);
40198944Sobrien	}
40219370Spst      if ((int) prec > (int) PREC_PREFIX)
40398944Sobrien	fputs_filtered (")", stream);
40419370Spst      return;
40519370Spst
40619370Spst    case BINOP_ASSIGN_MODIFY:
40719370Spst      opcode = exp->elts[pc + 1].opcode;
40819370Spst      (*pos) += 2;
40919370Spst      myprec = PREC_ASSIGN;
41019370Spst      assoc = 1;
41119370Spst      assign_modify = 1;
41219370Spst      op_str = "???";
41319370Spst      for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
41419370Spst	if (op_print_tab[tem].opcode == opcode)
41519370Spst	  {
41619370Spst	    op_str = op_print_tab[tem].string;
41719370Spst	    break;
41819370Spst	  }
41919370Spst      if (op_print_tab[tem].opcode != opcode)
42019370Spst	/* Not found; don't try to keep going because we don't know how
42119370Spst	   to interpret further elements.  */
42219370Spst	error ("Invalid expression");
42319370Spst      break;
42419370Spst
42598944Sobrien      /* C++ ops */
42619370Spst
42719370Spst    case OP_THIS:
42819370Spst      ++(*pos);
42919370Spst      fputs_filtered ("this", stream);
43019370Spst      return;
43119370Spst
432130803Smarcel      /* Objective-C ops */
433130803Smarcel
434130803Smarcel    case OP_OBJC_SELF:
435130803Smarcel      ++(*pos);
436130803Smarcel      fputs_filtered ("self", stream);	/* The ObjC equivalent of "this".  */
437130803Smarcel      return;
438130803Smarcel
43998944Sobrien      /* Modula-2 ops */
44019370Spst
44119370Spst    case MULTI_SUBSCRIPT:
44219370Spst      (*pos) += 2;
44319370Spst      nargs = longest_to_int (exp->elts[pc + 1].longconst);
44419370Spst      print_subexp (exp, pos, stream, PREC_SUFFIX);
44519370Spst      fprintf_unfiltered (stream, " [");
44619370Spst      for (tem = 0; tem < nargs; tem++)
44719370Spst	{
44819370Spst	  if (tem != 0)
44919370Spst	    fprintf_unfiltered (stream, ", ");
45019370Spst	  print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
45119370Spst	}
45219370Spst      fprintf_unfiltered (stream, "]");
45319370Spst      return;
45419370Spst
45519370Spst    case BINOP_VAL:
45698944Sobrien      (*pos) += 2;
45798944Sobrien      fprintf_unfiltered (stream, "VAL(");
45898944Sobrien      type_print (exp->elts[pc + 1].type, "", stream, 0);
45998944Sobrien      fprintf_unfiltered (stream, ",");
46098944Sobrien      print_subexp (exp, pos, stream, PREC_PREFIX);
46198944Sobrien      fprintf_unfiltered (stream, ")");
46219370Spst      return;
46398944Sobrien
46419370Spst    case BINOP_INCL:
46519370Spst    case BINOP_EXCL:
46698944Sobrien      error ("print_subexp:  Not implemented.");
46719370Spst
46898944Sobrien      /* Default ops */
46919370Spst
47019370Spst    default:
47119370Spst      op_str = "???";
47219370Spst      for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
47319370Spst	if (op_print_tab[tem].opcode == opcode)
47419370Spst	  {
47519370Spst	    op_str = op_print_tab[tem].string;
47619370Spst	    myprec = op_print_tab[tem].precedence;
47719370Spst	    assoc = op_print_tab[tem].right_assoc;
47819370Spst	    break;
47919370Spst	  }
48019370Spst      if (op_print_tab[tem].opcode != opcode)
48119370Spst	/* Not found; don't try to keep going because we don't know how
48219370Spst	   to interpret further elements.  For example, this happens
48319370Spst	   if opcode is OP_TYPE.  */
48419370Spst	error ("Invalid expression");
48598944Sobrien    }
48619370Spst
48719370Spst  /* Note that PREC_BUILTIN will always emit parentheses. */
48819370Spst  if ((int) myprec < (int) prec)
48919370Spst    fputs_filtered ("(", stream);
49019370Spst  if ((int) opcode > (int) BINOP_END)
49119370Spst    {
49219370Spst      if (assoc)
49319370Spst	{
49419370Spst	  /* Unary postfix operator.  */
49519370Spst	  print_subexp (exp, pos, stream, PREC_SUFFIX);
49619370Spst	  fputs_filtered (op_str, stream);
49719370Spst	}
49819370Spst      else
49919370Spst	{
50019370Spst	  /* Unary prefix operator.  */
50119370Spst	  fputs_filtered (op_str, stream);
50219370Spst	  if (myprec == PREC_BUILTIN_FUNCTION)
50319370Spst	    fputs_filtered ("(", stream);
50419370Spst	  print_subexp (exp, pos, stream, PREC_PREFIX);
50519370Spst	  if (myprec == PREC_BUILTIN_FUNCTION)
50619370Spst	    fputs_filtered (")", stream);
50719370Spst	}
50819370Spst    }
50919370Spst  else
51019370Spst    {
51119370Spst      /* Binary operator.  */
51219370Spst      /* Print left operand.
51398944Sobrien         If operator is right-associative,
51498944Sobrien         increment precedence for this operand.  */
51519370Spst      print_subexp (exp, pos, stream,
51619370Spst		    (enum precedence) ((int) myprec + assoc));
51719370Spst      /* Print the operator itself.  */
51819370Spst      if (assign_modify)
51919370Spst	fprintf_filtered (stream, " %s= ", op_str);
52019370Spst      else if (op_str[0] == ',')
52119370Spst	fprintf_filtered (stream, "%s ", op_str);
52219370Spst      else
52319370Spst	fprintf_filtered (stream, " %s ", op_str);
52419370Spst      /* Print right operand.
52598944Sobrien         If operator is left-associative,
52698944Sobrien         increment precedence for this operand.  */
52719370Spst      print_subexp (exp, pos, stream,
52819370Spst		    (enum precedence) ((int) myprec + !assoc));
52919370Spst    }
53019370Spst
53119370Spst  if ((int) myprec < (int) prec)
53219370Spst    fputs_filtered (")", stream);
53319370Spst}
53419370Spst
53519370Spst/* Return the operator corresponding to opcode OP as
53619370Spst   a string.   NULL indicates that the opcode was not found in the
53719370Spst   current language table.  */
53819370Spstchar *
53998944Sobrienop_string (enum exp_opcode op)
54019370Spst{
54119370Spst  int tem;
542130803Smarcel  const struct op_print *op_print_tab;
54319370Spst
54419370Spst  op_print_tab = current_language->la_op_print_tab;
54519370Spst  for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
54619370Spst    if (op_print_tab[tem].opcode == op)
54719370Spst      return op_print_tab[tem].string;
54819370Spst  return NULL;
54919370Spst}
55019370Spst
55119370Spst/* Support for dumping the raw data from expressions in a human readable
55219370Spst   form.  */
55319370Spst
554130803Smarcelstatic char *op_name (struct expression *, enum exp_opcode);
555130803Smarcelstatic int dump_subexp_body (struct expression *exp, struct ui_file *, int);
55646283Sdfr
557130803Smarcel/* Name for OPCODE, when it appears in expression EXP. */
558130803Smarcel
55946283Sdfrstatic char *
560130803Smarcelop_name (struct expression *exp, enum exp_opcode opcode)
56146283Sdfr{
562130803Smarcel  return exp->language_defn->la_exp_desc->op_name (opcode);
563130803Smarcel}
564130803Smarcel
565130803Smarcel/* Default name for the standard operator OPCODE (i.e., one defined in
566130803Smarcel   the definition of enum exp_opcode).  */
567130803Smarcel
568130803Smarcelchar *
569130803Smarcelop_name_standard (enum exp_opcode opcode)
570130803Smarcel{
57146283Sdfr  switch (opcode)
57246283Sdfr    {
57346283Sdfr    default:
57446283Sdfr      {
57546283Sdfr	static char buf[30];
57646283Sdfr
57746283Sdfr	sprintf (buf, "<unknown %d>", opcode);
57846283Sdfr	return buf;
57946283Sdfr      }
58098944Sobrien    case OP_NULL:
58198944Sobrien      return "OP_NULL";
58298944Sobrien    case BINOP_ADD:
58398944Sobrien      return "BINOP_ADD";
58498944Sobrien    case BINOP_SUB:
58598944Sobrien      return "BINOP_SUB";
58698944Sobrien    case BINOP_MUL:
58798944Sobrien      return "BINOP_MUL";
58898944Sobrien    case BINOP_DIV:
58998944Sobrien      return "BINOP_DIV";
59098944Sobrien    case BINOP_REM:
59198944Sobrien      return "BINOP_REM";
59298944Sobrien    case BINOP_MOD:
59398944Sobrien      return "BINOP_MOD";
59498944Sobrien    case BINOP_LSH:
59598944Sobrien      return "BINOP_LSH";
59698944Sobrien    case BINOP_RSH:
59798944Sobrien      return "BINOP_RSH";
59898944Sobrien    case BINOP_LOGICAL_AND:
59998944Sobrien      return "BINOP_LOGICAL_AND";
60098944Sobrien    case BINOP_LOGICAL_OR:
60198944Sobrien      return "BINOP_LOGICAL_OR";
60298944Sobrien    case BINOP_BITWISE_AND:
60398944Sobrien      return "BINOP_BITWISE_AND";
60498944Sobrien    case BINOP_BITWISE_IOR:
60598944Sobrien      return "BINOP_BITWISE_IOR";
60698944Sobrien    case BINOP_BITWISE_XOR:
60798944Sobrien      return "BINOP_BITWISE_XOR";
60898944Sobrien    case BINOP_EQUAL:
60998944Sobrien      return "BINOP_EQUAL";
61098944Sobrien    case BINOP_NOTEQUAL:
61198944Sobrien      return "BINOP_NOTEQUAL";
61298944Sobrien    case BINOP_LESS:
61398944Sobrien      return "BINOP_LESS";
61498944Sobrien    case BINOP_GTR:
61598944Sobrien      return "BINOP_GTR";
61698944Sobrien    case BINOP_LEQ:
61798944Sobrien      return "BINOP_LEQ";
61898944Sobrien    case BINOP_GEQ:
61998944Sobrien      return "BINOP_GEQ";
62098944Sobrien    case BINOP_REPEAT:
62198944Sobrien      return "BINOP_REPEAT";
62298944Sobrien    case BINOP_ASSIGN:
62398944Sobrien      return "BINOP_ASSIGN";
62498944Sobrien    case BINOP_COMMA:
62598944Sobrien      return "BINOP_COMMA";
62698944Sobrien    case BINOP_SUBSCRIPT:
62798944Sobrien      return "BINOP_SUBSCRIPT";
62898944Sobrien    case MULTI_SUBSCRIPT:
62998944Sobrien      return "MULTI_SUBSCRIPT";
63098944Sobrien    case BINOP_EXP:
63198944Sobrien      return "BINOP_EXP";
63298944Sobrien    case BINOP_MIN:
63398944Sobrien      return "BINOP_MIN";
63498944Sobrien    case BINOP_MAX:
63598944Sobrien      return "BINOP_MAX";
63698944Sobrien    case STRUCTOP_MEMBER:
63798944Sobrien      return "STRUCTOP_MEMBER";
63898944Sobrien    case STRUCTOP_MPTR:
63998944Sobrien      return "STRUCTOP_MPTR";
64098944Sobrien    case BINOP_INTDIV:
64198944Sobrien      return "BINOP_INTDIV";
64298944Sobrien    case BINOP_ASSIGN_MODIFY:
64398944Sobrien      return "BINOP_ASSIGN_MODIFY";
64498944Sobrien    case BINOP_VAL:
64598944Sobrien      return "BINOP_VAL";
64698944Sobrien    case BINOP_INCL:
64798944Sobrien      return "BINOP_INCL";
64898944Sobrien    case BINOP_EXCL:
64998944Sobrien      return "BINOP_EXCL";
65098944Sobrien    case BINOP_CONCAT:
65198944Sobrien      return "BINOP_CONCAT";
65298944Sobrien    case BINOP_RANGE:
65398944Sobrien      return "BINOP_RANGE";
65498944Sobrien    case BINOP_END:
65598944Sobrien      return "BINOP_END";
65698944Sobrien    case TERNOP_COND:
65798944Sobrien      return "TERNOP_COND";
65898944Sobrien    case TERNOP_SLICE:
65998944Sobrien      return "TERNOP_SLICE";
66098944Sobrien    case TERNOP_SLICE_COUNT:
66198944Sobrien      return "TERNOP_SLICE_COUNT";
66298944Sobrien    case OP_LONG:
66398944Sobrien      return "OP_LONG";
66498944Sobrien    case OP_DOUBLE:
66598944Sobrien      return "OP_DOUBLE";
66698944Sobrien    case OP_VAR_VALUE:
66798944Sobrien      return "OP_VAR_VALUE";
66898944Sobrien    case OP_LAST:
66998944Sobrien      return "OP_LAST";
67098944Sobrien    case OP_REGISTER:
67198944Sobrien      return "OP_REGISTER";
67298944Sobrien    case OP_INTERNALVAR:
67398944Sobrien      return "OP_INTERNALVAR";
67498944Sobrien    case OP_FUNCALL:
67598944Sobrien      return "OP_FUNCALL";
67698944Sobrien    case OP_STRING:
67798944Sobrien      return "OP_STRING";
67898944Sobrien    case OP_BITSTRING:
67998944Sobrien      return "OP_BITSTRING";
68098944Sobrien    case OP_ARRAY:
68198944Sobrien      return "OP_ARRAY";
68298944Sobrien    case UNOP_CAST:
68398944Sobrien      return "UNOP_CAST";
68498944Sobrien    case UNOP_MEMVAL:
68598944Sobrien      return "UNOP_MEMVAL";
68698944Sobrien    case UNOP_NEG:
68798944Sobrien      return "UNOP_NEG";
68898944Sobrien    case UNOP_LOGICAL_NOT:
68998944Sobrien      return "UNOP_LOGICAL_NOT";
69098944Sobrien    case UNOP_COMPLEMENT:
69198944Sobrien      return "UNOP_COMPLEMENT";
69298944Sobrien    case UNOP_IND:
69398944Sobrien      return "UNOP_IND";
69498944Sobrien    case UNOP_ADDR:
69598944Sobrien      return "UNOP_ADDR";
69698944Sobrien    case UNOP_PREINCREMENT:
69798944Sobrien      return "UNOP_PREINCREMENT";
69898944Sobrien    case UNOP_POSTINCREMENT:
69998944Sobrien      return "UNOP_POSTINCREMENT";
70098944Sobrien    case UNOP_PREDECREMENT:
70198944Sobrien      return "UNOP_PREDECREMENT";
70298944Sobrien    case UNOP_POSTDECREMENT:
70398944Sobrien      return "UNOP_POSTDECREMENT";
70498944Sobrien    case UNOP_SIZEOF:
70598944Sobrien      return "UNOP_SIZEOF";
70698944Sobrien    case UNOP_LOWER:
70798944Sobrien      return "UNOP_LOWER";
70898944Sobrien    case UNOP_UPPER:
70998944Sobrien      return "UNOP_UPPER";
71098944Sobrien    case UNOP_LENGTH:
71198944Sobrien      return "UNOP_LENGTH";
71298944Sobrien    case UNOP_PLUS:
71398944Sobrien      return "UNOP_PLUS";
71498944Sobrien    case UNOP_CAP:
71598944Sobrien      return "UNOP_CAP";
71698944Sobrien    case UNOP_CHR:
71798944Sobrien      return "UNOP_CHR";
71898944Sobrien    case UNOP_ORD:
71998944Sobrien      return "UNOP_ORD";
72098944Sobrien    case UNOP_ABS:
72198944Sobrien      return "UNOP_ABS";
72298944Sobrien    case UNOP_FLOAT:
72398944Sobrien      return "UNOP_FLOAT";
72498944Sobrien    case UNOP_HIGH:
72598944Sobrien      return "UNOP_HIGH";
72698944Sobrien    case UNOP_MAX:
72798944Sobrien      return "UNOP_MAX";
72898944Sobrien    case UNOP_MIN:
72998944Sobrien      return "UNOP_MIN";
73098944Sobrien    case UNOP_ODD:
73198944Sobrien      return "UNOP_ODD";
73298944Sobrien    case UNOP_TRUNC:
73398944Sobrien      return "UNOP_TRUNC";
73498944Sobrien    case OP_BOOL:
73598944Sobrien      return "OP_BOOL";
73698944Sobrien    case OP_M2_STRING:
73798944Sobrien      return "OP_M2_STRING";
73898944Sobrien    case STRUCTOP_STRUCT:
73998944Sobrien      return "STRUCTOP_STRUCT";
74098944Sobrien    case STRUCTOP_PTR:
74198944Sobrien      return "STRUCTOP_PTR";
74298944Sobrien    case OP_THIS:
74398944Sobrien      return "OP_THIS";
744130803Smarcel    case OP_OBJC_SELF:
745130803Smarcel      return "OP_OBJC_SELF";
74698944Sobrien    case OP_SCOPE:
74798944Sobrien      return "OP_SCOPE";
74898944Sobrien    case OP_TYPE:
74998944Sobrien      return "OP_TYPE";
75098944Sobrien    case OP_LABELED:
75198944Sobrien      return "OP_LABELED";
75246283Sdfr    }
75346283Sdfr}
75446283Sdfr
75519370Spstvoid
756130803Smarceldump_raw_expression (struct expression *exp, struct ui_file *stream,
757130803Smarcel		     char *note)
75819370Spst{
75919370Spst  int elt;
76019370Spst  char *opcode_name;
76119370Spst  char *eltscan;
76219370Spst  int eltsize;
76319370Spst
76419370Spst  fprintf_filtered (stream, "Dump of expression @ ");
76598944Sobrien  gdb_print_host_address (exp, stream);
76698944Sobrien  fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
76798944Sobrien		    exp->language_defn->la_name, exp->nelts,
76898944Sobrien		    (long) sizeof (union exp_element));
76919370Spst  fprintf_filtered (stream, "\t%5s  %20s  %16s  %s\n", "Index", "Opcode",
77019370Spst		    "Hex Value", "String Value");
77198944Sobrien  for (elt = 0; elt < exp->nelts; elt++)
77219370Spst    {
77319370Spst      fprintf_filtered (stream, "\t%5d  ", elt);
774130803Smarcel      opcode_name = op_name (exp, exp->elts[elt].opcode);
77546283Sdfr
77619370Spst      fprintf_filtered (stream, "%20s  ", opcode_name);
77798944Sobrien      print_longest (stream, 'd', 0, exp->elts[elt].longconst);
77846283Sdfr      fprintf_filtered (stream, "  ");
77919370Spst
78019370Spst      for (eltscan = (char *) &exp->elts[elt],
78198944Sobrien	   eltsize = sizeof (union exp_element);
78219370Spst	   eltsize-- > 0;
78319370Spst	   eltscan++)
78419370Spst	{
78519370Spst	  fprintf_filtered (stream, "%c",
78619370Spst			    isprint (*eltscan) ? (*eltscan & 0xFF) : '.');
78719370Spst	}
78819370Spst      fprintf_filtered (stream, "\n");
78919370Spst    }
79019370Spst}
79119370Spst
792130803Smarcel/* Dump the subexpression of prefix expression EXP whose operator is at
793130803Smarcel   position ELT onto STREAM.  Returns the position of the next
794130803Smarcel   subexpression in EXP.  */
79546283Sdfr
796130803Smarcelint
79798944Sobriendump_subexp (struct expression *exp, struct ui_file *stream, int elt)
79846283Sdfr{
79946283Sdfr  static int indent = 0;
80046283Sdfr  int i;
80146283Sdfr
80246283Sdfr  fprintf_filtered (stream, "\n");
80346283Sdfr  fprintf_filtered (stream, "\t%5d  ", elt);
80446283Sdfr
80546283Sdfr  for (i = 1; i <= indent; i++)
80646283Sdfr    fprintf_filtered (stream, " ");
80746283Sdfr  indent += 2;
80846283Sdfr
809130803Smarcel  fprintf_filtered (stream, "%-20s  ", op_name (exp, exp->elts[elt].opcode));
81046283Sdfr
811130803Smarcel  elt = dump_subexp_body (exp, stream, elt);
812130803Smarcel
813130803Smarcel  indent -= 2;
814130803Smarcel
815130803Smarcel  return elt;
816130803Smarcel}
817130803Smarcel
818130803Smarcel/* Dump the operands of prefix expression EXP whose opcode is at
819130803Smarcel   position ELT onto STREAM.  Returns the position of the next
820130803Smarcel   subexpression in EXP.  */
821130803Smarcel
822130803Smarcelstatic int
823130803Smarceldump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
824130803Smarcel{
825130803Smarcel  return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt);
826130803Smarcel}
827130803Smarcel
828130803Smarcel/* Default value for subexp_body in exp_descriptor vector.  */
829130803Smarcel
830130803Smarcelint
831130803Smarceldump_subexp_body_standard (struct expression *exp,
832130803Smarcel			   struct ui_file *stream, int elt)
833130803Smarcel{
834130803Smarcel  int opcode = exp->elts[elt++].opcode;
835130803Smarcel
836130803Smarcel  switch (opcode)
83746283Sdfr    {
83846283Sdfr    case TERNOP_COND:
83946283Sdfr    case TERNOP_SLICE:
84046283Sdfr    case TERNOP_SLICE_COUNT:
84146283Sdfr      elt = dump_subexp (exp, stream, elt);
84246283Sdfr    case BINOP_ADD:
84346283Sdfr    case BINOP_SUB:
84446283Sdfr    case BINOP_MUL:
84546283Sdfr    case BINOP_DIV:
84646283Sdfr    case BINOP_REM:
84746283Sdfr    case BINOP_MOD:
84846283Sdfr    case BINOP_LSH:
84946283Sdfr    case BINOP_RSH:
85046283Sdfr    case BINOP_LOGICAL_AND:
85146283Sdfr    case BINOP_LOGICAL_OR:
85246283Sdfr    case BINOP_BITWISE_AND:
85346283Sdfr    case BINOP_BITWISE_IOR:
85446283Sdfr    case BINOP_BITWISE_XOR:
85546283Sdfr    case BINOP_EQUAL:
85646283Sdfr    case BINOP_NOTEQUAL:
85746283Sdfr    case BINOP_LESS:
85846283Sdfr    case BINOP_GTR:
85946283Sdfr    case BINOP_LEQ:
86046283Sdfr    case BINOP_GEQ:
86146283Sdfr    case BINOP_REPEAT:
86246283Sdfr    case BINOP_ASSIGN:
86346283Sdfr    case BINOP_COMMA:
86446283Sdfr    case BINOP_SUBSCRIPT:
86546283Sdfr    case BINOP_EXP:
86646283Sdfr    case BINOP_MIN:
86746283Sdfr    case BINOP_MAX:
86846283Sdfr    case BINOP_INTDIV:
86946283Sdfr    case BINOP_ASSIGN_MODIFY:
87046283Sdfr    case BINOP_VAL:
87146283Sdfr    case BINOP_INCL:
87246283Sdfr    case BINOP_EXCL:
87346283Sdfr    case BINOP_CONCAT:
87446283Sdfr    case BINOP_IN:
87546283Sdfr    case BINOP_RANGE:
87646283Sdfr    case BINOP_END:
87746283Sdfr      elt = dump_subexp (exp, stream, elt);
87846283Sdfr    case UNOP_NEG:
87946283Sdfr    case UNOP_LOGICAL_NOT:
88046283Sdfr    case UNOP_COMPLEMENT:
88146283Sdfr    case UNOP_IND:
88246283Sdfr    case UNOP_ADDR:
88346283Sdfr    case UNOP_PREINCREMENT:
88446283Sdfr    case UNOP_POSTINCREMENT:
88546283Sdfr    case UNOP_PREDECREMENT:
88646283Sdfr    case UNOP_POSTDECREMENT:
88746283Sdfr    case UNOP_SIZEOF:
88846283Sdfr    case UNOP_PLUS:
88946283Sdfr    case UNOP_CAP:
89046283Sdfr    case UNOP_CHR:
89146283Sdfr    case UNOP_ORD:
89246283Sdfr    case UNOP_ABS:
89346283Sdfr    case UNOP_FLOAT:
89446283Sdfr    case UNOP_HIGH:
89546283Sdfr    case UNOP_MAX:
89646283Sdfr    case UNOP_MIN:
89746283Sdfr    case UNOP_ODD:
89846283Sdfr    case UNOP_TRUNC:
89946283Sdfr    case UNOP_LOWER:
90046283Sdfr    case UNOP_UPPER:
90146283Sdfr    case UNOP_LENGTH:
90246283Sdfr    case UNOP_CARD:
90346283Sdfr    case UNOP_CHMAX:
90446283Sdfr    case UNOP_CHMIN:
90546283Sdfr      elt = dump_subexp (exp, stream, elt);
90646283Sdfr      break;
90746283Sdfr    case OP_LONG:
90898944Sobrien      fprintf_filtered (stream, "Type @");
90998944Sobrien      gdb_print_host_address (exp->elts[elt].type, stream);
91098944Sobrien      fprintf_filtered (stream, " (");
91146283Sdfr      type_print (exp->elts[elt].type, NULL, stream, 0);
91246283Sdfr      fprintf_filtered (stream, "), value %ld (0x%lx)",
91398944Sobrien			(long) exp->elts[elt + 1].longconst,
91498944Sobrien			(long) exp->elts[elt + 1].longconst);
91546283Sdfr      elt += 3;
91646283Sdfr      break;
91746283Sdfr    case OP_DOUBLE:
91898944Sobrien      fprintf_filtered (stream, "Type @");
91998944Sobrien      gdb_print_host_address (exp->elts[elt].type, stream);
92098944Sobrien      fprintf_filtered (stream, " (");
92146283Sdfr      type_print (exp->elts[elt].type, NULL, stream, 0);
92246283Sdfr      fprintf_filtered (stream, "), value %g",
92398944Sobrien			(double) exp->elts[elt + 1].doubleconst);
92446283Sdfr      elt += 3;
92546283Sdfr      break;
92646283Sdfr    case OP_VAR_VALUE:
92798944Sobrien      fprintf_filtered (stream, "Block @");
92898944Sobrien      gdb_print_host_address (exp->elts[elt].block, stream);
92998944Sobrien      fprintf_filtered (stream, ", symbol @");
93098944Sobrien      gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
93198944Sobrien      fprintf_filtered (stream, " (%s)",
932130803Smarcel			DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol));
93346283Sdfr      elt += 3;
93446283Sdfr      break;
93546283Sdfr    case OP_LAST:
93646283Sdfr      fprintf_filtered (stream, "History element %ld",
93798944Sobrien			(long) exp->elts[elt].longconst);
93846283Sdfr      elt += 2;
93946283Sdfr      break;
94046283Sdfr    case OP_REGISTER:
94146283Sdfr      fprintf_filtered (stream, "Register %ld",
94298944Sobrien			(long) exp->elts[elt].longconst);
94346283Sdfr      elt += 2;
94446283Sdfr      break;
94546283Sdfr    case OP_INTERNALVAR:
94698944Sobrien      fprintf_filtered (stream, "Internal var @");
94798944Sobrien      gdb_print_host_address (exp->elts[elt].internalvar, stream);
94898944Sobrien      fprintf_filtered (stream, " (%s)",
94946283Sdfr			exp->elts[elt].internalvar->name);
95046283Sdfr      elt += 2;
95146283Sdfr      break;
95246283Sdfr    case OP_FUNCALL:
95346283Sdfr      {
954130803Smarcel	int i, nargs;
95546283Sdfr
95646283Sdfr	nargs = longest_to_int (exp->elts[elt].longconst);
95746283Sdfr
95846283Sdfr	fprintf_filtered (stream, "Number of args: %d", nargs);
95946283Sdfr	elt += 2;
96046283Sdfr
96146283Sdfr	for (i = 1; i <= nargs + 1; i++)
96246283Sdfr	  elt = dump_subexp (exp, stream, elt);
96346283Sdfr      }
96446283Sdfr      break;
96546283Sdfr    case OP_ARRAY:
96646283Sdfr      {
96746283Sdfr	int lower, upper;
96846283Sdfr	int i;
96946283Sdfr
97046283Sdfr	lower = longest_to_int (exp->elts[elt].longconst);
97146283Sdfr	upper = longest_to_int (exp->elts[elt + 1].longconst);
97246283Sdfr
97346283Sdfr	fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper);
97446283Sdfr	elt += 3;
97546283Sdfr
97646283Sdfr	for (i = 1; i <= upper - lower + 1; i++)
97746283Sdfr	  elt = dump_subexp (exp, stream, elt);
97846283Sdfr      }
97946283Sdfr      break;
98046283Sdfr    case UNOP_MEMVAL:
98146283Sdfr    case UNOP_CAST:
98298944Sobrien      fprintf_filtered (stream, "Type @");
98398944Sobrien      gdb_print_host_address (exp->elts[elt].type, stream);
98498944Sobrien      fprintf_filtered (stream, " (");
98546283Sdfr      type_print (exp->elts[elt].type, NULL, stream, 0);
98646283Sdfr      fprintf_filtered (stream, ")");
98746283Sdfr      elt = dump_subexp (exp, stream, elt + 2);
98846283Sdfr      break;
98946283Sdfr    case OP_TYPE:
99098944Sobrien      fprintf_filtered (stream, "Type @");
99198944Sobrien      gdb_print_host_address (exp->elts[elt].type, stream);
99298944Sobrien      fprintf_filtered (stream, " (");
99346283Sdfr      type_print (exp->elts[elt].type, NULL, stream, 0);
99446283Sdfr      fprintf_filtered (stream, ")");
99546283Sdfr      elt += 2;
99646283Sdfr      break;
99746283Sdfr    case STRUCTOP_STRUCT:
99846283Sdfr    case STRUCTOP_PTR:
99946283Sdfr      {
100046283Sdfr	char *elem_name;
100146283Sdfr	int len;
100246283Sdfr
100346283Sdfr	len = longest_to_int (exp->elts[elt].longconst);
100446283Sdfr	elem_name = &exp->elts[elt + 1].string;
100546283Sdfr
100646283Sdfr	fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name);
100746283Sdfr	elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1));
100846283Sdfr      }
100946283Sdfr      break;
101046283Sdfr    case OP_SCOPE:
101146283Sdfr      {
101246283Sdfr	char *elem_name;
101346283Sdfr	int len;
101446283Sdfr
101598944Sobrien	fprintf_filtered (stream, "Type @");
101698944Sobrien	gdb_print_host_address (exp->elts[elt].type, stream);
101798944Sobrien	fprintf_filtered (stream, " (");
101846283Sdfr	type_print (exp->elts[elt].type, NULL, stream, 0);
101946283Sdfr	fprintf_filtered (stream, ") ");
102046283Sdfr
102146283Sdfr	len = longest_to_int (exp->elts[elt + 1].longconst);
102246283Sdfr	elem_name = &exp->elts[elt + 2].string;
102346283Sdfr
102446283Sdfr	fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name);
102546283Sdfr	elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
102646283Sdfr      }
102746283Sdfr      break;
102846283Sdfr    default:
102946283Sdfr    case OP_NULL:
103046283Sdfr    case STRUCTOP_MEMBER:
103146283Sdfr    case STRUCTOP_MPTR:
103246283Sdfr    case MULTI_SUBSCRIPT:
103346283Sdfr    case OP_F77_UNDETERMINED_ARGLIST:
103446283Sdfr    case OP_COMPLEX:
103546283Sdfr    case OP_STRING:
103646283Sdfr    case OP_BITSTRING:
103746283Sdfr    case OP_BOOL:
103846283Sdfr    case OP_M2_STRING:
103946283Sdfr    case OP_THIS:
104046283Sdfr    case OP_LABELED:
104146283Sdfr    case OP_NAME:
104246283Sdfr    case OP_EXPRSTRING:
104346283Sdfr      fprintf_filtered (stream, "Unknown format");
104446283Sdfr    }
104546283Sdfr
104646283Sdfr  return elt;
104746283Sdfr}
104846283Sdfr
104946283Sdfrvoid
1050130803Smarceldump_prefix_expression (struct expression *exp, struct ui_file *stream)
105146283Sdfr{
105246283Sdfr  int elt;
105346283Sdfr
105446283Sdfr  fprintf_filtered (stream, "Dump of expression @ ");
105598944Sobrien  gdb_print_host_address (exp, stream);
1056130803Smarcel  fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
105746283Sdfr  if (exp->elts[0].opcode != OP_TYPE)
105846283Sdfr    print_expression (exp, stream);
105946283Sdfr  else
106046283Sdfr    fputs_filtered ("Type printing not yet supported....", stream);
106198944Sobrien  fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
106298944Sobrien		    exp->language_defn->la_name, exp->nelts,
106398944Sobrien		    (long) sizeof (union exp_element));
106446283Sdfr  fputs_filtered ("\n", stream);
106546283Sdfr
106698944Sobrien  for (elt = 0; elt < exp->nelts;)
106746283Sdfr    elt = dump_subexp (exp, stream, elt);
106846283Sdfr  fputs_filtered ("\n", stream);
106946283Sdfr}
1070