Set dynamic tag VMA and size from dynamic section when possible
[external/binutils.git] / gdb / expprint.c
index d0e940b..b3337cd 100644 (file)
@@ -1,13 +1,12 @@
 /* Print in infix form a struct expression.
 
 /* Print in infix form a struct expression.
 
-   Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
 
 #include "defs.h"
 #include "symtab.h"
 #include "value.h"
 #include "language.h"
 #include "parser-defs.h"
 #include "value.h"
 #include "language.h"
 #include "parser-defs.h"
-#include "frame.h"             /* For frame_map_regnum_to_name.  */
+#include "user-regs.h"         /* For user_reg_map_regnum_to_name.  */
 #include "target.h"
 #include "target.h"
-#include "gdb_string.h"
 #include "block.h"
 #include "block.h"
+#include "objfiles.h"
+#include "valprint.h"
 
 
-#ifdef HAVE_CTYPE_H
 #include <ctype.h>
 #include <ctype.h>
-#endif
-
-/* Prototypes for local functions */
-
-static void print_subexp (struct expression *, int *, struct ui_file *,
-                         enum precedence);
 
 void
 print_expression (struct expression *exp, struct ui_file *stream)
 {
   int pc = 0;
 
 void
 print_expression (struct expression *exp, struct ui_file *stream)
 {
   int pc = 0;
+
   print_subexp (exp, &pc, stream, PREC_NULL);
 }
 
   print_subexp (exp, &pc, stream, PREC_NULL);
 }
 
@@ -53,15 +45,24 @@ print_expression (struct expression *exp, struct ui_file *stream)
    if the precedence of the main operator of this subexpression is less,
    parentheses are needed here.  */
 
    if the precedence of the main operator of this subexpression is less,
    parentheses are needed here.  */
 
-static void
-print_subexp (register struct expression *exp, register int *pos,
+void
+print_subexp (struct expression *exp, int *pos,
              struct ui_file *stream, enum precedence prec)
 {
              struct ui_file *stream, enum precedence prec)
 {
-  register unsigned tem;
-  register const struct op_print *op_print_tab;
-  register int pc;
+  exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec);
+}
+
+/* Standard implementation of print_subexp for use in language_defn
+   vectors.  */
+void
+print_subexp_standard (struct expression *exp, int *pos,
+                      struct ui_file *stream, enum precedence prec)
+{
+  unsigned tem;
+  const struct op_print *op_print_tab;
+  int pc;
   unsigned nargs;
   unsigned nargs;
-  register char *op_str;
+  char *op_str;
   int assign_modify = 0;
   enum exp_opcode opcode;
   enum precedence myprec = PREC_NULL;
   int assign_modify = 0;
   enum exp_opcode opcode;
   enum precedence myprec = PREC_NULL;
@@ -77,6 +78,11 @@ print_subexp (register struct expression *exp, register int *pos,
     {
       /* Common ops */
 
     {
       /* Common ops */
 
+    case OP_TYPE:
+      (*pos) += 2;
+      type_print (exp->elts[pc + 1].type, "", stream, 0);
+      return;
+
     case OP_SCOPE:
       myprec = PREC_PREFIX;
       assoc = 0;
     case OP_SCOPE:
       myprec = PREC_PREFIX;
       assoc = 0;
@@ -88,22 +94,33 @@ print_subexp (register struct expression *exp, register int *pos,
       return;
 
     case OP_LONG:
       return;
 
     case OP_LONG:
-      (*pos) += 3;
-      value_print (value_from_longest (exp->elts[pc + 1].type,
-                                      exp->elts[pc + 2].longconst),
-                  stream, 0, Val_no_prettyprint);
+      {
+       struct value_print_options opts;
+
+       get_no_prettyformat_print_options (&opts);
+       (*pos) += 3;
+       value_print (value_from_longest (exp->elts[pc + 1].type,
+                                        exp->elts[pc + 2].longconst),
+                    stream, &opts);
+      }
       return;
 
     case OP_DOUBLE:
       return;
 
     case OP_DOUBLE:
-      (*pos) += 3;
-      value_print (value_from_double (exp->elts[pc + 1].type,
-                                     exp->elts[pc + 2].doubleconst),
-                  stream, 0, Val_no_prettyprint);
+      {
+       struct value_print_options opts;
+
+       get_no_prettyformat_print_options (&opts);
+       (*pos) += 3;
+       value_print (value_from_double (exp->elts[pc + 1].type,
+                                       exp->elts[pc + 2].doubleconst),
+                    stream, &opts);
+      }
       return;
 
     case OP_VAR_VALUE:
       {
       return;
 
     case OP_VAR_VALUE:
       {
-       struct block *b;
+       const struct block *b;
+
        (*pos) += 3;
        b = exp->elts[pc + 1].block;
        if (b != NULL
        (*pos) += 3;
        b = exp->elts[pc + 1].block;
        if (b != NULL
@@ -117,6 +134,14 @@ print_subexp (register struct expression *exp, register int *pos,
       }
       return;
 
       }
       return;
 
+    case OP_VAR_ENTRY_VALUE:
+      {
+       (*pos) += 2;
+       fprintf_filtered (stream, "%s@entry",
+                         SYMBOL_PRINT_NAME (exp->elts[pc + 1].symbol));
+      }
+      return;
+
     case OP_LAST:
       (*pos) += 2;
       fprintf_filtered (stream, "$%d",
     case OP_LAST:
       (*pos) += 2;
       fprintf_filtered (stream, "$%d",
@@ -125,9 +150,10 @@ print_subexp (register struct expression *exp, register int *pos,
 
     case OP_REGISTER:
       {
 
     case OP_REGISTER:
       {
-       int regnum = longest_to_int (exp->elts[pc + 1].longconst);
-       (*pos) += 2;
-       fprintf_filtered (stream, "$%s", frame_map_regnum_to_name (regnum));
+       const char *name = &exp->elts[pc + 2].string;
+
+       (*pos) += 3 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
+       fprintf_filtered (stream, "$%s", name);
        return;
       }
 
        return;
       }
 
@@ -159,39 +185,47 @@ print_subexp (register struct expression *exp, register int *pos,
       return;
 
     case OP_NAME:
       return;
 
     case OP_NAME:
-    case OP_EXPRSTRING:
       nargs = longest_to_int (exp->elts[pc + 1].longconst);
       (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
     case OP_STRING:
       nargs = longest_to_int (exp->elts[pc + 1].longconst);
       (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
     case OP_STRING:
-      nargs = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
-      /* LA_PRINT_STRING will print using the current repeat count threshold.
-         If necessary, we can temporarily set it to zero, or pass it as an
-         additional parameter to LA_PRINT_STRING.  -fnf */
-      LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0);
-      return;
-
-    case OP_BITSTRING:
-      nargs = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos)
-       += 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
-      fprintf_unfiltered (stream, "B'<unimplemented>'");
+      {
+       struct value_print_options opts;
+
+       nargs = longest_to_int (exp->elts[pc + 1].longconst);
+       (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
+       /* LA_PRINT_STRING will print using the current repeat count threshold.
+          If necessary, we can temporarily set it to zero, or pass it as an
+          additional parameter to LA_PRINT_STRING.  -fnf */
+       get_user_print_options (&opts);
+       LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
+                        (gdb_byte *) &exp->elts[pc + 2].string, nargs,
+                        NULL, 0, &opts);
+      }
       return;
 
       return;
 
-    case OP_OBJC_NSSTRING:     /* Objective-C Foundation Class NSString constant.  */
-      nargs = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
-      fputs_filtered ("@\"", stream);
-      LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0);
-      fputs_filtered ("\"", stream);
+    case OP_OBJC_NSSTRING:     /* Objective-C Foundation Class
+                                  NSString constant.  */
+      {
+       struct value_print_options opts;
+
+       nargs = longest_to_int (exp->elts[pc + 1].longconst);
+       (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
+       fputs_filtered ("@\"", stream);
+       get_user_print_options (&opts);
+       LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
+                        (gdb_byte *) &exp->elts[pc + 2].string, nargs,
+                        NULL, 0, &opts);
+       fputs_filtered ("\"", stream);
+      }
       return;
 
     case OP_OBJC_MSGCALL:
       {                        /* Objective C message (method) call.  */
        char *selector;
       return;
 
     case OP_OBJC_MSGCALL:
       {                        /* Objective C message (method) call.  */
        char *selector;
+
        (*pos) += 3;
        nargs = longest_to_int (exp->elts[pc + 2].longconst);
        fprintf_unfiltered (stream, "[");
        (*pos) += 3;
        nargs = longest_to_int (exp->elts[pc + 2].longconst);
        fprintf_unfiltered (stream, "[");
@@ -199,17 +233,19 @@ print_subexp (register struct expression *exp, register int *pos,
        if (0 == target_read_string (exp->elts[pc + 1].longconst,
                                     &selector, 1024, NULL))
          {
        if (0 == target_read_string (exp->elts[pc + 1].longconst,
                                     &selector, 1024, NULL))
          {
-           error ("bad selector");
+           error (_("bad selector"));
            return;
          }
        if (nargs)
          {
            char *s, *nextS;
            return;
          }
        if (nargs)
          {
            char *s, *nextS;
-           s = alloca (strlen (selector) + 1);
+
+           s = (char *) alloca (strlen (selector) + 1);
            strcpy (s, selector);
            for (tem = 0; tem < nargs; tem++)
              {
                nextS = strchr (s, ':');
            strcpy (s, selector);
            for (tem = 0; tem < nargs; tem++)
              {
                nextS = strchr (s, ':');
+               gdb_assert (nextS);     /* Make sure we found ':'.  */
                *nextS = '\0';
                fprintf_unfiltered (stream, " %s: ", s);
                s = nextS + 1;
                *nextS = '\0';
                fprintf_unfiltered (stream, " %s: ", s);
                s = nextS + 1;
@@ -221,7 +257,7 @@ print_subexp (register struct expression *exp, register int *pos,
            fprintf_unfiltered (stream, " %s", selector);
          }
        fprintf_unfiltered (stream, "]");
            fprintf_unfiltered (stream, " %s", selector);
          }
        fprintf_unfiltered (stream, "]");
-       /* "selector" was malloc'd by target_read_string. Free it.  */
+       /* "selector" was malloc'd by target_read_string.  Free it.  */
        xfree (selector);
        return;
       }
        xfree (selector);
        return;
       }
@@ -233,7 +269,8 @@ print_subexp (register struct expression *exp, register int *pos,
       nargs++;
       tem = 0;
       if (exp->elts[pc + 4].opcode == OP_LONG
       nargs++;
       tem = 0;
       if (exp->elts[pc + 4].opcode == OP_LONG
-         && exp->elts[pc + 5].type == builtin_type_char
+         && exp->elts[pc + 5].type
+            == builtin_type (exp->gdbarch)->builtin_char
          && exp->language_defn->la_language == language_c)
        {
          /* Attempt to print C character arrays using string syntax.
          && exp->language_defn->la_language == language_c)
        {
          /* Attempt to print C character arrays using string syntax.
@@ -242,15 +279,17 @@ print_subexp (register struct expression *exp, register int *pos,
             does not match our expection of what we should find for
             a simple string, revert back to array printing.  Note that
             the last expression element is an explicit null terminator
             does not match our expection of what we should find for
             a simple string, revert back to array printing.  Note that
             the last expression element is an explicit null terminator
-            byte, which doesn't get printed. */
-         tempstr = alloca (nargs);
+            byte, which doesn't get printed.  */
+         tempstr = (char *) alloca (nargs);
          pc += 4;
          while (tem < nargs)
            {
              if (exp->elts[pc].opcode != OP_LONG
          pc += 4;
          while (tem < nargs)
            {
              if (exp->elts[pc].opcode != OP_LONG
-                 || exp->elts[pc + 1].type != builtin_type_char)
+                 || exp->elts[pc + 1].type
+                    != builtin_type (exp->gdbarch)->builtin_char)
                {
                {
-                 /* Not a simple array of char, use regular array printing. */
+                 /* Not a simple array of char, use regular array
+                    printing.  */
                  tem = 0;
                  break;
                }
                  tem = 0;
                  break;
                }
@@ -264,7 +303,11 @@ print_subexp (register struct expression *exp, register int *pos,
        }
       if (tem > 0)
        {
        }
       if (tem > 0)
        {
-         LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0);
+         struct value_print_options opts;
+
+         get_user_print_options (&opts);
+         LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
+                          (gdb_byte *) tempstr, nargs - 1, NULL, 0, &opts);
          (*pos) = pc;
        }
       else
          (*pos) = pc;
        }
       else
@@ -282,21 +325,6 @@ print_subexp (register struct expression *exp, register int *pos,
        }
       return;
 
        }
       return;
 
-    case OP_LABELED:
-      tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-      /* Gcc support both these syntaxes.  Unsure which is preferred.  */
-#if 1
-      fputs_filtered (&exp->elts[pc + 2].string, stream);
-      fputs_filtered (": ", stream);
-#else
-      fputs_filtered (".", stream);
-      fputs_filtered (&exp->elts[pc + 2].string, stream);
-      fputs_filtered ("=", stream);
-#endif
-      print_subexp (exp, pos, stream, PREC_SUFFIX);
-      return;
-
     case TERNOP_COND:
       if ((int) prec > (int) PREC_COMMA)
        fputs_filtered ("(", stream);
     case TERNOP_COND:
       if ((int) prec > (int) PREC_COMMA)
        fputs_filtered ("(", stream);
@@ -314,7 +342,6 @@ print_subexp (register struct expression *exp, register int *pos,
       return;
 
     case TERNOP_SLICE:
       return;
 
     case TERNOP_SLICE:
-    case TERNOP_SLICE_COUNT:
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered ("(", stream);
       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered ("(", stream);
       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
@@ -331,7 +358,7 @@ print_subexp (register struct expression *exp, register int *pos,
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
-      /* Will not occur for Modula-2 */
+      /* Will not occur for Modula-2 */
     case STRUCTOP_PTR:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
       (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
     case STRUCTOP_PTR:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
       (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
@@ -340,6 +367,18 @@ print_subexp (register struct expression *exp, register int *pos,
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
+    case STRUCTOP_MEMBER:
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      fputs_filtered (".*", stream);
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      return;
+
+    case STRUCTOP_MPTR:
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      fputs_filtered ("->*", stream);
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      return;
+
     case BINOP_SUBSCRIPT:
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered ("[", stream);
     case BINOP_SUBSCRIPT:
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered ("[", stream);
@@ -369,22 +408,46 @@ print_subexp (register struct expression *exp, register int *pos,
        fputs_filtered (")", stream);
       return;
 
        fputs_filtered (")", stream);
       return;
 
+    case UNOP_CAST_TYPE:
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered ("(", stream);
+      fputs_filtered ("(", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      fputs_filtered (") ", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered (")", stream);
+      return;
+
+    case UNOP_DYNAMIC_CAST:
+    case UNOP_REINTERPRET_CAST:
+      fputs_filtered (opcode == UNOP_DYNAMIC_CAST ? "dynamic_cast"
+                     : "reinterpret_cast", stream);
+      fputs_filtered ("<", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      fputs_filtered ("> (", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      fputs_filtered (")", stream);
+      return;
+
     case UNOP_MEMVAL:
       (*pos) += 2;
       if ((int) prec > (int) PREC_PREFIX)
        fputs_filtered ("(", stream);
     case UNOP_MEMVAL:
       (*pos) += 2;
       if ((int) prec > (int) PREC_PREFIX)
        fputs_filtered ("(", stream);
-      if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC &&
-         exp->elts[pc + 3].opcode == OP_LONG)
+      if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC
+         && exp->elts[pc + 3].opcode == OP_LONG)
        {
        {
+         struct value_print_options opts;
+
          /* We have a minimal symbol fn, probably.  It's encoded
             as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
             Swallow the OP_LONG (including both its opcodes); ignore
             its type; print the value in the type of the MEMVAL.  */
          (*pos) += 4;
          val = value_at_lazy (exp->elts[pc + 1].type,
          /* We have a minimal symbol fn, probably.  It's encoded
             as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
             Swallow the OP_LONG (including both its opcodes); ignore
             its type; print the value in the type of the MEMVAL.  */
          (*pos) += 4;
          val = value_at_lazy (exp->elts[pc + 1].type,
-                              (CORE_ADDR) exp->elts[pc + 5].longconst,
-                              NULL);
-         value_print (val, stream, 0, Val_no_prettyprint);
+                              (CORE_ADDR) exp->elts[pc + 5].longconst);
+         get_no_prettyformat_print_options (&opts);
+         value_print (val, stream, &opts);
        }
       else
        {
        }
       else
        {
@@ -397,6 +460,29 @@ print_subexp (register struct expression *exp, register int *pos,
        fputs_filtered (")", stream);
       return;
 
        fputs_filtered (")", stream);
       return;
 
+    case UNOP_MEMVAL_TYPE:
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered ("(", stream);
+      fputs_filtered ("{", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      fputs_filtered ("} ", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered (")", stream);
+      return;
+
+    case UNOP_MEMVAL_TLS:
+      (*pos) += 3;
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered ("(", stream);
+      fputs_filtered ("{", stream);
+      type_print (exp->elts[pc + 2].type, "", stream, 0);
+      fputs_filtered ("} ", stream);
+      print_subexp (exp, pos, stream, PREC_PREFIX);
+      if ((int) prec > (int) PREC_PREFIX)
+       fputs_filtered (")", stream);
+      return;
+
     case BINOP_ASSIGN_MODIFY:
       opcode = exp->elts[pc + 1].opcode;
       (*pos) += 2;
     case BINOP_ASSIGN_MODIFY:
       opcode = exp->elts[pc + 1].opcode;
       (*pos) += 2;
@@ -413,21 +499,18 @@ print_subexp (register struct expression *exp, register int *pos,
       if (op_print_tab[tem].opcode != opcode)
        /* Not found; don't try to keep going because we don't know how
           to interpret further elements.  */
       if (op_print_tab[tem].opcode != opcode)
        /* Not found; don't try to keep going because we don't know how
           to interpret further elements.  */
-       error ("Invalid expression");
+       error (_("Invalid expression"));
       break;
 
       /* C++ ops */
 
     case OP_THIS:
       ++(*pos);
       break;
 
       /* C++ ops */
 
     case OP_THIS:
       ++(*pos);
-      fputs_filtered ("this", stream);
-      return;
-
-      /* Objective-C ops */
-
-    case OP_OBJC_SELF:
-      ++(*pos);
-      fputs_filtered ("self", stream); /* The ObjC equivalent of "this".  */
+      if (exp->language_defn->la_name_of_this)
+       fputs_filtered (exp->language_defn->la_name_of_this, stream);
+      else
+       fprintf_filtered (stream, _("<language %s has no 'this'>"),
+                         exp->language_defn->la_name);
       return;
 
       /* Modula-2 ops */
       return;
 
       /* Modula-2 ops */
@@ -455,9 +538,26 @@ print_subexp (register struct expression *exp, register int *pos,
       fprintf_unfiltered (stream, ")");
       return;
 
       fprintf_unfiltered (stream, ")");
       return;
 
-    case BINOP_INCL:
-    case BINOP_EXCL:
-      error ("print_subexp:  Not implemented.");
+    case TYPE_INSTANCE:
+      {
+       LONGEST count = exp->elts[pc + 1].longconst;
+
+       /* The COUNT.  */
+       (*pos)++;
+       fputs_unfiltered ("TypesInstance(", stream);
+       while (count-- > 0)
+         {
+           type_print (exp->elts[(*pos)++].type, "", stream, 0);
+           if (count > 0)
+             fputs_unfiltered (",", stream);
+         }
+       fputs_unfiltered (",", stream);
+       /* Ending COUNT and ending TYPE_INSTANCE.  */
+       (*pos) += 2;
+       print_subexp (exp, pos, stream, PREC_PREFIX);
+       fputs_unfiltered (")", stream);
+       return;
+      }
 
       /* Default ops */
 
 
       /* Default ops */
 
@@ -475,10 +575,10 @@ print_subexp (register struct expression *exp, register int *pos,
        /* Not found; don't try to keep going because we don't know how
           to interpret further elements.  For example, this happens
           if opcode is OP_TYPE.  */
        /* Not found; don't try to keep going because we don't know how
           to interpret further elements.  For example, this happens
           if opcode is OP_TYPE.  */
-       error ("Invalid expression");
+       error (_("Invalid expression"));
     }
 
     }
 
-  /* Note that PREC_BUILTIN will always emit parentheses. */
+  /* Note that PREC_BUILTIN will always emit parentheses.  */
   if ((int) myprec < (int) prec)
     fputs_filtered ("(", stream);
   if ((int) opcode > (int) BINOP_END)
   if ((int) myprec < (int) prec)
     fputs_filtered ("(", stream);
   if ((int) opcode > (int) BINOP_END)
@@ -533,7 +633,7 @@ char *
 op_string (enum exp_opcode op)
 {
   int tem;
 op_string (enum exp_opcode op)
 {
   int tem;
-  register const struct op_print *op_print_tab;
+  const struct op_print *op_print_tab;
 
   op_print_tab = current_language->la_op_print_tab;
   for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
 
   op_print_tab = current_language->la_op_print_tab;
   for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
@@ -545,10 +645,21 @@ op_string (enum exp_opcode op)
 /* Support for dumping the raw data from expressions in a human readable
    form.  */
 
 /* Support for dumping the raw data from expressions in a human readable
    form.  */
 
-static char *op_name (int opcode);
+static int dump_subexp_body (struct expression *exp, struct ui_file *, int);
 
 
-static char *
-op_name (int opcode)
+/* Name for OPCODE, when it appears in expression EXP.  */
+
+char *
+op_name (struct expression *exp, enum exp_opcode opcode)
+{
+  return exp->language_defn->la_exp_desc->op_name (opcode);
+}
+
+/* Default name for the standard operator OPCODE (i.e., one defined in
+   the definition of enum exp_opcode).  */
+
+char *
+op_name_standard (enum exp_opcode opcode)
 {
   switch (opcode)
     {
 {
   switch (opcode)
     {
@@ -556,187 +667,23 @@ op_name (int opcode)
       {
        static char buf[30];
 
       {
        static char buf[30];
 
-       sprintf (buf, "<unknown %d>", opcode);
+       xsnprintf (buf, sizeof (buf), "<unknown %d>", opcode);
        return buf;
       }
        return buf;
       }
-    case OP_NULL:
-      return "OP_NULL";
-    case BINOP_ADD:
-      return "BINOP_ADD";
-    case BINOP_SUB:
-      return "BINOP_SUB";
-    case BINOP_MUL:
-      return "BINOP_MUL";
-    case BINOP_DIV:
-      return "BINOP_DIV";
-    case BINOP_REM:
-      return "BINOP_REM";
-    case BINOP_MOD:
-      return "BINOP_MOD";
-    case BINOP_LSH:
-      return "BINOP_LSH";
-    case BINOP_RSH:
-      return "BINOP_RSH";
-    case BINOP_LOGICAL_AND:
-      return "BINOP_LOGICAL_AND";
-    case BINOP_LOGICAL_OR:
-      return "BINOP_LOGICAL_OR";
-    case BINOP_BITWISE_AND:
-      return "BINOP_BITWISE_AND";
-    case BINOP_BITWISE_IOR:
-      return "BINOP_BITWISE_IOR";
-    case BINOP_BITWISE_XOR:
-      return "BINOP_BITWISE_XOR";
-    case BINOP_EQUAL:
-      return "BINOP_EQUAL";
-    case BINOP_NOTEQUAL:
-      return "BINOP_NOTEQUAL";
-    case BINOP_LESS:
-      return "BINOP_LESS";
-    case BINOP_GTR:
-      return "BINOP_GTR";
-    case BINOP_LEQ:
-      return "BINOP_LEQ";
-    case BINOP_GEQ:
-      return "BINOP_GEQ";
-    case BINOP_REPEAT:
-      return "BINOP_REPEAT";
-    case BINOP_ASSIGN:
-      return "BINOP_ASSIGN";
-    case BINOP_COMMA:
-      return "BINOP_COMMA";
-    case BINOP_SUBSCRIPT:
-      return "BINOP_SUBSCRIPT";
-    case MULTI_SUBSCRIPT:
-      return "MULTI_SUBSCRIPT";
-    case BINOP_EXP:
-      return "BINOP_EXP";
-    case BINOP_MIN:
-      return "BINOP_MIN";
-    case BINOP_MAX:
-      return "BINOP_MAX";
-    case STRUCTOP_MEMBER:
-      return "STRUCTOP_MEMBER";
-    case STRUCTOP_MPTR:
-      return "STRUCTOP_MPTR";
-    case BINOP_INTDIV:
-      return "BINOP_INTDIV";
-    case BINOP_ASSIGN_MODIFY:
-      return "BINOP_ASSIGN_MODIFY";
-    case BINOP_VAL:
-      return "BINOP_VAL";
-    case BINOP_INCL:
-      return "BINOP_INCL";
-    case BINOP_EXCL:
-      return "BINOP_EXCL";
-    case BINOP_CONCAT:
-      return "BINOP_CONCAT";
-    case BINOP_RANGE:
-      return "BINOP_RANGE";
-    case BINOP_END:
-      return "BINOP_END";
-    case TERNOP_COND:
-      return "TERNOP_COND";
-    case TERNOP_SLICE:
-      return "TERNOP_SLICE";
-    case TERNOP_SLICE_COUNT:
-      return "TERNOP_SLICE_COUNT";
-    case OP_LONG:
-      return "OP_LONG";
-    case OP_DOUBLE:
-      return "OP_DOUBLE";
-    case OP_VAR_VALUE:
-      return "OP_VAR_VALUE";
-    case OP_LAST:
-      return "OP_LAST";
-    case OP_REGISTER:
-      return "OP_REGISTER";
-    case OP_INTERNALVAR:
-      return "OP_INTERNALVAR";
-    case OP_FUNCALL:
-      return "OP_FUNCALL";
-    case OP_STRING:
-      return "OP_STRING";
-    case OP_BITSTRING:
-      return "OP_BITSTRING";
-    case OP_ARRAY:
-      return "OP_ARRAY";
-    case UNOP_CAST:
-      return "UNOP_CAST";
-    case UNOP_MEMVAL:
-      return "UNOP_MEMVAL";
-    case UNOP_NEG:
-      return "UNOP_NEG";
-    case UNOP_LOGICAL_NOT:
-      return "UNOP_LOGICAL_NOT";
-    case UNOP_COMPLEMENT:
-      return "UNOP_COMPLEMENT";
-    case UNOP_IND:
-      return "UNOP_IND";
-    case UNOP_ADDR:
-      return "UNOP_ADDR";
-    case UNOP_PREINCREMENT:
-      return "UNOP_PREINCREMENT";
-    case UNOP_POSTINCREMENT:
-      return "UNOP_POSTINCREMENT";
-    case UNOP_PREDECREMENT:
-      return "UNOP_PREDECREMENT";
-    case UNOP_POSTDECREMENT:
-      return "UNOP_POSTDECREMENT";
-    case UNOP_SIZEOF:
-      return "UNOP_SIZEOF";
-    case UNOP_LOWER:
-      return "UNOP_LOWER";
-    case UNOP_UPPER:
-      return "UNOP_UPPER";
-    case UNOP_LENGTH:
-      return "UNOP_LENGTH";
-    case UNOP_PLUS:
-      return "UNOP_PLUS";
-    case UNOP_CAP:
-      return "UNOP_CAP";
-    case UNOP_CHR:
-      return "UNOP_CHR";
-    case UNOP_ORD:
-      return "UNOP_ORD";
-    case UNOP_ABS:
-      return "UNOP_ABS";
-    case UNOP_FLOAT:
-      return "UNOP_FLOAT";
-    case UNOP_HIGH:
-      return "UNOP_HIGH";
-    case UNOP_MAX:
-      return "UNOP_MAX";
-    case UNOP_MIN:
-      return "UNOP_MIN";
-    case UNOP_ODD:
-      return "UNOP_ODD";
-    case UNOP_TRUNC:
-      return "UNOP_TRUNC";
-    case OP_BOOL:
-      return "OP_BOOL";
-    case OP_M2_STRING:
-      return "OP_M2_STRING";
-    case STRUCTOP_STRUCT:
-      return "STRUCTOP_STRUCT";
-    case STRUCTOP_PTR:
-      return "STRUCTOP_PTR";
-    case OP_THIS:
-      return "OP_THIS";
-    case OP_OBJC_SELF:
-      return "OP_OBJC_SELF";
-    case OP_SCOPE:
-      return "OP_SCOPE";
-    case OP_TYPE:
-      return "OP_TYPE";
-    case OP_LABELED:
-      return "OP_LABELED";
+#define OP(name)       \
+    case name:         \
+      return #name ;
+#include "std-operator.def"
+#undef OP
     }
 }
 
     }
 }
 
+/* Print a raw dump of expression EXP to STREAM.
+   NOTE, if non-NULL, is printed as extra explanatory text.  */
+
 void
 void
-dump_prefix_expression (struct expression *exp, struct ui_file *stream,
-                       char *note)
+dump_raw_expression (struct expression *exp, struct ui_file *stream,
+                    char *note)
 {
   int elt;
   char *opcode_name;
 {
   int elt;
   char *opcode_name;
@@ -745,12 +692,9 @@ dump_prefix_expression (struct expression *exp, struct ui_file *stream,
 
   fprintf_filtered (stream, "Dump of expression @ ");
   gdb_print_host_address (exp, stream);
 
   fprintf_filtered (stream, "Dump of expression @ ");
   gdb_print_host_address (exp, stream);
-  fprintf_filtered (stream, ", %s:\nExpression: `", note);
-  if (exp->elts[0].opcode != OP_TYPE)
-    print_expression (exp, stream);
-  else
-    fprintf_filtered (stream, "Type printing not yet supported....");
-  fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
+  if (note)
+    fprintf_filtered (stream, ", %s:", note);
+  fprintf_filtered (stream, "\n\tLanguage %s, %d elements, %ld bytes each.\n",
                    exp->language_defn->la_name, exp->nelts,
                    (long) sizeof (union exp_element));
   fprintf_filtered (stream, "\t%5s  %20s  %16s  %s\n", "Index", "Opcode",
                    exp->language_defn->la_name, exp->nelts,
                    (long) sizeof (union exp_element));
   fprintf_filtered (stream, "\t%5s  %20s  %16s  %s\n", "Index", "Opcode",
@@ -758,7 +702,7 @@ dump_prefix_expression (struct expression *exp, struct ui_file *stream,
   for (elt = 0; elt < exp->nelts; elt++)
     {
       fprintf_filtered (stream, "\t%5d  ", elt);
   for (elt = 0; elt < exp->nelts; elt++)
     {
       fprintf_filtered (stream, "\t%5d  ", elt);
-      opcode_name = op_name (exp->elts[elt].opcode);
+      opcode_name = op_name (exp, exp->elts[elt].opcode);
 
       fprintf_filtered (stream, "%20s  ", opcode_name);
       print_longest (stream, 'd', 0, exp->elts[elt].longconst);
 
       fprintf_filtered (stream, "%20s  ", opcode_name);
       print_longest (stream, 'd', 0, exp->elts[elt].longconst);
@@ -776,10 +720,11 @@ dump_prefix_expression (struct expression *exp, struct ui_file *stream,
     }
 }
 
     }
 }
 
-static int dump_subexp (struct expression *exp, struct ui_file *stream,
-                       int elt);
+/* Dump the subexpression of prefix expression EXP whose operator is at
+   position ELT onto STREAM.  Returns the position of the next 
+   subexpression in EXP.  */
 
 
-static int
+int
 dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
 {
   static int indent = 0;
 dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
 {
   static int indent = 0;
@@ -792,14 +737,39 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
     fprintf_filtered (stream, " ");
   indent += 2;
 
     fprintf_filtered (stream, " ");
   indent += 2;
 
-  fprintf_filtered (stream, "%-20s  ", op_name (exp->elts[elt].opcode));
+  fprintf_filtered (stream, "%-20s  ", op_name (exp, exp->elts[elt].opcode));
+
+  elt = dump_subexp_body (exp, stream, elt);
+
+  indent -= 2;
+
+  return elt;
+}
+
+/* Dump the operands of prefix expression EXP whose opcode is at
+   position ELT onto STREAM.  Returns the position of the next 
+   subexpression in EXP.  */
+
+static int
+dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
+{
+  return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt);
+}
 
 
-  switch (exp->elts[elt++].opcode)
+/* Default value for subexp_body in exp_descriptor vector.  */
+
+int
+dump_subexp_body_standard (struct expression *exp, 
+                          struct ui_file *stream, int elt)
+{
+  int opcode = exp->elts[elt++].opcode;
+
+  switch (opcode)
     {
     case TERNOP_COND:
     case TERNOP_SLICE:
     {
     case TERNOP_COND:
     case TERNOP_SLICE:
-    case TERNOP_SLICE_COUNT:
       elt = dump_subexp (exp, stream, elt);
       elt = dump_subexp (exp, stream, elt);
+      /* FALL THROUGH */
     case BINOP_ADD:
     case BINOP_SUB:
     case BINOP_MUL:
     case BINOP_ADD:
     case BINOP_SUB:
     case BINOP_MUL:
@@ -829,13 +799,12 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
     case BINOP_INTDIV:
     case BINOP_ASSIGN_MODIFY:
     case BINOP_VAL:
     case BINOP_INTDIV:
     case BINOP_ASSIGN_MODIFY:
     case BINOP_VAL:
-    case BINOP_INCL:
-    case BINOP_EXCL:
     case BINOP_CONCAT:
     case BINOP_CONCAT:
-    case BINOP_IN:
-    case BINOP_RANGE:
     case BINOP_END:
     case BINOP_END:
+    case STRUCTOP_MEMBER:
+    case STRUCTOP_MPTR:
       elt = dump_subexp (exp, stream, elt);
       elt = dump_subexp (exp, stream, elt);
+      /* FALL THROUGH */
     case UNOP_NEG:
     case UNOP_LOGICAL_NOT:
     case UNOP_COMPLEMENT:
     case UNOP_NEG:
     case UNOP_LOGICAL_NOT:
     case UNOP_COMPLEMENT:
@@ -857,12 +826,6 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
     case UNOP_MIN:
     case UNOP_ODD:
     case UNOP_TRUNC:
     case UNOP_MIN:
     case UNOP_ODD:
     case UNOP_TRUNC:
-    case UNOP_LOWER:
-    case UNOP_UPPER:
-    case UNOP_LENGTH:
-    case UNOP_CARD:
-    case UNOP_CHMAX:
-    case UNOP_CHMIN:
       elt = dump_subexp (exp, stream, elt);
       break;
     case OP_LONG:
       elt = dump_subexp (exp, stream, elt);
       break;
     case OP_LONG:
@@ -890,29 +853,35 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
       fprintf_filtered (stream, ", symbol @");
       gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
       fprintf_filtered (stream, " (%s)",
       fprintf_filtered (stream, ", symbol @");
       gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
       fprintf_filtered (stream, " (%s)",
-                       DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol));
+                       SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol));
       elt += 3;
       break;
       elt += 3;
       break;
+    case OP_VAR_ENTRY_VALUE:
+      fprintf_filtered (stream, "Entry value of symbol @");
+      gdb_print_host_address (exp->elts[elt].symbol, stream);
+      fprintf_filtered (stream, " (%s)",
+                       SYMBOL_PRINT_NAME (exp->elts[elt].symbol));
+      elt += 2;
+      break;
     case OP_LAST:
       fprintf_filtered (stream, "History element %ld",
                        (long) exp->elts[elt].longconst);
       elt += 2;
       break;
     case OP_REGISTER:
     case OP_LAST:
       fprintf_filtered (stream, "History element %ld",
                        (long) exp->elts[elt].longconst);
       elt += 2;
       break;
     case OP_REGISTER:
-      fprintf_filtered (stream, "Register %ld",
-                       (long) exp->elts[elt].longconst);
-      elt += 2;
+      fprintf_filtered (stream, "Register $%s", &exp->elts[elt + 1].string);
+      elt += 3 + BYTES_TO_EXP_ELEM (exp->elts[elt].longconst + 1);
       break;
     case OP_INTERNALVAR:
       fprintf_filtered (stream, "Internal var @");
       gdb_print_host_address (exp->elts[elt].internalvar, stream);
       fprintf_filtered (stream, " (%s)",
       break;
     case OP_INTERNALVAR:
       fprintf_filtered (stream, "Internal var @");
       gdb_print_host_address (exp->elts[elt].internalvar, stream);
       fprintf_filtered (stream, " (%s)",
-                       exp->elts[elt].internalvar->name);
+                       internalvar_name (exp->elts[elt].internalvar));
       elt += 2;
       break;
     case OP_FUNCALL:
       {
       elt += 2;
       break;
     case OP_FUNCALL:
       {
-       int nargs;
+       int i, nargs;
 
        nargs = longest_to_int (exp->elts[elt].longconst);
 
 
        nargs = longest_to_int (exp->elts[elt].longconst);
 
@@ -938,6 +907,15 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
          elt = dump_subexp (exp, stream, elt);
       }
       break;
          elt = dump_subexp (exp, stream, elt);
       }
       break;
+    case UNOP_DYNAMIC_CAST:
+    case UNOP_REINTERPRET_CAST:
+    case UNOP_CAST_TYPE:
+    case UNOP_MEMVAL_TYPE:
+      fprintf_filtered (stream, " (");
+      elt = dump_subexp (exp, stream, elt);
+      fprintf_filtered (stream, ")");
+      elt = dump_subexp (exp, stream, elt);
+      break;
     case UNOP_MEMVAL:
     case UNOP_CAST:
       fprintf_filtered (stream, "Type @");
     case UNOP_MEMVAL:
     case UNOP_CAST:
       fprintf_filtered (stream, "Type @");
@@ -947,6 +925,16 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
       fprintf_filtered (stream, ")");
       elt = dump_subexp (exp, stream, elt + 2);
       break;
       fprintf_filtered (stream, ")");
       elt = dump_subexp (exp, stream, elt + 2);
       break;
+    case UNOP_MEMVAL_TLS:
+      fprintf_filtered (stream, "TLS type @");
+      gdb_print_host_address (exp->elts[elt + 1].type, stream);
+      fprintf_filtered (stream, " (__thread /* \"%s\" */ ",
+                        (exp->elts[elt].objfile == NULL ? "(null)"
+                        : objfile_name (exp->elts[elt].objfile)));
+      type_print (exp->elts[elt + 1].type, NULL, stream, 0);
+      fprintf_filtered (stream, ")");
+      elt = dump_subexp (exp, stream, elt + 3);
+      break;
     case OP_TYPE:
       fprintf_filtered (stream, "Type @");
       gdb_print_host_address (exp->elts[elt].type, stream);
     case OP_TYPE:
       fprintf_filtered (stream, "Type @");
       gdb_print_host_address (exp->elts[elt].type, stream);
@@ -955,6 +943,17 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
       fprintf_filtered (stream, ")");
       elt += 2;
       break;
       fprintf_filtered (stream, ")");
       elt += 2;
       break;
+    case OP_TYPEOF:
+    case OP_DECLTYPE:
+      fprintf_filtered (stream, "Typeof (");
+      elt = dump_subexp (exp, stream, elt);
+      fprintf_filtered (stream, ")");
+      break;
+    case OP_TYPEID:
+      fprintf_filtered (stream, "typeid (");
+      elt = dump_subexp (exp, stream, elt);
+      fprintf_filtered (stream, ")");
+      break;
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       {
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
       {
@@ -986,42 +985,70 @@ dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
        elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
       }
       break;
        elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
       }
       break;
+    case TYPE_INSTANCE:
+      {
+       LONGEST len;
+
+       len = exp->elts[elt++].longconst;
+       fprintf_filtered (stream, "%s TypeInstance: ", plongest (len));
+       while (len-- > 0)
+         {
+           fprintf_filtered (stream, "Type @");
+           gdb_print_host_address (exp->elts[elt].type, stream);
+           fprintf_filtered (stream, " (");
+           type_print (exp->elts[elt].type, NULL, stream, 0);
+           fprintf_filtered (stream, ")");
+           elt++;
+           if (len > 0)
+             fputs_filtered (", ", stream);
+         }
+       /* Ending LEN and ending TYPE_INSTANCE.  */
+       elt += 2;
+       elt = dump_subexp (exp, stream, elt);
+      }
+      break;
+    case OP_STRING:
+      {
+       LONGEST len = exp->elts[elt].longconst;
+       LONGEST type = exp->elts[elt + 1].longconst;
+
+       fprintf_filtered (stream, "Language-specific string type: %s",
+                         plongest (type));
+
+       /* Skip length.  */
+       elt += 1;
+
+       /* Skip string content. */
+       elt += BYTES_TO_EXP_ELEM (len);
+
+       /* Skip length and ending OP_STRING. */
+       elt += 2;
+      }
+      break;
     default:
     case OP_NULL:
     default:
     case OP_NULL:
-    case STRUCTOP_MEMBER:
-    case STRUCTOP_MPTR:
     case MULTI_SUBSCRIPT:
     case OP_F77_UNDETERMINED_ARGLIST:
     case OP_COMPLEX:
     case MULTI_SUBSCRIPT:
     case OP_F77_UNDETERMINED_ARGLIST:
     case OP_COMPLEX:
-    case OP_STRING:
-    case OP_BITSTRING:
     case OP_BOOL:
     case OP_M2_STRING:
     case OP_THIS:
     case OP_BOOL:
     case OP_M2_STRING:
     case OP_THIS:
-    case OP_LABELED:
     case OP_NAME:
     case OP_NAME:
-    case OP_EXPRSTRING:
       fprintf_filtered (stream, "Unknown format");
     }
 
       fprintf_filtered (stream, "Unknown format");
     }
 
-  indent -= 2;
-
   return elt;
 }
 
 void
   return elt;
 }
 
 void
-dump_postfix_expression (struct expression *exp, struct ui_file *stream,
-                        char *note)
+dump_prefix_expression (struct expression *exp, struct ui_file *stream)
 {
   int elt;
 
   fprintf_filtered (stream, "Dump of expression @ ");
   gdb_print_host_address (exp, stream);
 {
   int elt;
 
   fprintf_filtered (stream, "Dump of expression @ ");
   gdb_print_host_address (exp, stream);
-  fprintf_filtered (stream, ", %s:\nExpression: `", note);
-  if (exp->elts[0].opcode != OP_TYPE)
-    print_expression (exp, stream);
-  else
-    fputs_filtered ("Type printing not yet supported....", stream);
+  fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
+  print_expression (exp, stream);
   fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
                    exp->language_defn->la_name, exp->nelts,
                    (long) sizeof (union exp_element));
   fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n",
                    exp->language_defn->la_name, exp->nelts,
                    (long) sizeof (union exp_element));