+ fputs_filtered (")", stream);
+}
+
+/* Return the operator corresponding to opcode OP as
+ a string. NULL indicates that the opcode was not found in the
+ current language table. */
+char *
+op_string (enum exp_opcode op)
+{
+ int tem;
+ 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++)
+ if (op_print_tab[tem].opcode == op)
+ return op_print_tab[tem].string;
+ return NULL;
+}
+
+/* Support for dumping the raw data from expressions in a human readable
+ form. */
+
+static char *op_name (struct expression *, enum exp_opcode);
+static int dump_subexp_body (struct expression *exp, struct ui_file *, int);
+
+/* Name for OPCODE, when it appears in expression EXP. */
+
+static 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)
+ {
+ default:
+ {
+ static char buf[30];
+
+ sprintf (buf, "<unknown %d>", opcode);
+ 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_MEMVAL_TLS:
+ return "UNOP_MEMVAL_TLS";
+ 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";
+ }
+}
+
+void
+dump_raw_expression (struct expression *exp, struct ui_file *stream,
+ char *note)
+{
+ int elt;
+ char *opcode_name;
+ char *eltscan;
+ int eltsize;
+
+ fprintf_filtered (stream, "Dump of expression @ ");
+ gdb_print_host_address (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, "\t%5s %20s %16s %s\n", "Index", "Opcode",
+ "Hex Value", "String Value");
+ for (elt = 0; elt < exp->nelts; elt++)
+ {
+ fprintf_filtered (stream, "\t%5d ", elt);
+ 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, " ");
+
+ for (eltscan = (char *) &exp->elts[elt],
+ eltsize = sizeof (union exp_element);
+ eltsize-- > 0;
+ eltscan++)
+ {
+ fprintf_filtered (stream, "%c",
+ isprint (*eltscan) ? (*eltscan & 0xFF) : '.');
+ }
+ fprintf_filtered (stream, "\n");
+ }
+}
+
+/* Dump the subexpression of prefix expression EXP whose operator is at
+ position ELT onto STREAM. Returns the position of the next
+ subexpression in EXP. */
+
+int
+dump_subexp (struct expression *exp, struct ui_file *stream, int elt)
+{
+ static int indent = 0;
+ int i;
+
+ fprintf_filtered (stream, "\n");
+ fprintf_filtered (stream, "\t%5d ", elt);
+
+ for (i = 1; i <= indent; i++)
+ fprintf_filtered (stream, " ");
+ indent += 2;
+
+ 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);
+}
+
+/* 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_SLICE_COUNT:
+ elt = dump_subexp (exp, stream, elt);
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_MOD:
+ case BINOP_LSH:
+ case BINOP_RSH:
+ case BINOP_LOGICAL_AND:
+ case BINOP_LOGICAL_OR:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
+ case BINOP_REPEAT:
+ case BINOP_ASSIGN:
+ case BINOP_COMMA:
+ case BINOP_SUBSCRIPT:
+ case BINOP_EXP:
+ case BINOP_MIN:
+ case BINOP_MAX:
+ case BINOP_INTDIV:
+ case BINOP_ASSIGN_MODIFY:
+ case BINOP_VAL:
+ case BINOP_INCL:
+ case BINOP_EXCL:
+ case BINOP_CONCAT:
+ case BINOP_IN:
+ case BINOP_RANGE:
+ case BINOP_END:
+ case STRUCTOP_MEMBER:
+ case STRUCTOP_MPTR:
+ elt = dump_subexp (exp, stream, elt);
+ case UNOP_NEG:
+ case UNOP_LOGICAL_NOT:
+ case UNOP_COMPLEMENT:
+ case UNOP_IND:
+ case UNOP_ADDR:
+ case UNOP_PREINCREMENT:
+ case UNOP_POSTINCREMENT:
+ case UNOP_PREDECREMENT:
+ case UNOP_POSTDECREMENT:
+ case UNOP_SIZEOF:
+ case UNOP_PLUS:
+ case UNOP_CAP:
+ case UNOP_CHR:
+ case UNOP_ORD:
+ case UNOP_ABS:
+ case UNOP_FLOAT:
+ case UNOP_HIGH:
+ case UNOP_MAX:
+ 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:
+ 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, "), value %ld (0x%lx)",
+ (long) exp->elts[elt + 1].longconst,
+ (long) exp->elts[elt + 1].longconst);
+ elt += 3;
+ break;
+ case OP_DOUBLE:
+ 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, "), value %g",
+ (double) exp->elts[elt + 1].doubleconst);
+ elt += 3;
+ break;
+ case OP_VAR_VALUE:
+ fprintf_filtered (stream, "Block @");
+ gdb_print_host_address (exp->elts[elt].block, stream);
+ fprintf_filtered (stream, ", symbol @");
+ gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
+ fprintf_filtered (stream, " (%s)",
+ SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol));
+ elt += 3;
+ break;
+ case OP_LAST:
+ fprintf_filtered (stream, "History element %ld",
+ (long) exp->elts[elt].longconst);
+ elt += 2;
+ break;
+ case OP_REGISTER:
+ 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)",
+ exp->elts[elt].internalvar->name);
+ elt += 2;
+ break;
+ case OP_FUNCALL:
+ {
+ int i, nargs;
+
+ nargs = longest_to_int (exp->elts[elt].longconst);
+
+ fprintf_filtered (stream, "Number of args: %d", nargs);
+ elt += 2;
+
+ for (i = 1; i <= nargs + 1; i++)
+ elt = dump_subexp (exp, stream, elt);
+ }
+ break;
+ case OP_ARRAY:
+ {
+ int lower, upper;
+ int i;
+
+ lower = longest_to_int (exp->elts[elt].longconst);
+ upper = longest_to_int (exp->elts[elt + 1].longconst);
+
+ fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper);
+ elt += 3;
+
+ for (i = 1; i <= upper - lower + 1; i++)
+ elt = dump_subexp (exp, stream, elt);
+ }
+ break;
+ case UNOP_MEMVAL:
+ case UNOP_CAST:
+ 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 = 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)"
+ : exp->elts[elt].objfile->name));
+ 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);
+ fprintf_filtered (stream, " (");
+ type_print (exp->elts[elt].type, NULL, stream, 0);
+ fprintf_filtered (stream, ")");
+ elt += 2;
+ break;
+ case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
+ {
+ char *elem_name;
+ int len;
+
+ len = longest_to_int (exp->elts[elt].longconst);
+ elem_name = &exp->elts[elt + 1].string;
+
+ fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name);
+ elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1));
+ }
+ break;
+ case OP_SCOPE:
+ {
+ char *elem_name;
+ int len;
+
+ 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, ") ");
+
+ len = longest_to_int (exp->elts[elt + 1].longconst);
+ elem_name = &exp->elts[elt + 2].string;
+
+ fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name);
+ elt += 4 + BYTES_TO_EXP_ELEM (len + 1);
+ }
+ break;
+ default:
+ case OP_NULL:
+ 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_LABELED:
+ case OP_NAME:
+ fprintf_filtered (stream, "Unknown format");
+ }
+
+ return elt;
+}
+
+void
+dump_prefix_expression (struct expression *exp, struct ui_file *stream)
+{
+ int elt;
+
+ fprintf_filtered (stream, "Dump of expression @ ");
+ gdb_print_host_address (exp, stream);
+ fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
+ if (exp->elts[0].opcode != OP_TYPE)
+ print_expression (exp, stream);
+ else
+ fputs_filtered ("Type printing not yet supported....", 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));
+ fputs_filtered ("\n", stream);
+
+ for (elt = 0; elt < exp->nelts;)
+ elt = dump_subexp (exp, stream, elt);
+ fputs_filtered ("\n", stream);