/* Print in infix form a struct expression.
+
Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
This file is part of GDB.
#include "value.h"
#include "language.h"
#include "parser-defs.h"
+#include "user-regs.h" /* For user_reg_map_regnum_to_name. */
+#include "target.h"
+#include "gdb_string.h"
+#include "block.h"
#ifdef HAVE_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)
{
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)
{
- 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;
- register char *op_str;
+ char *op_str;
int assign_modify = 0;
enum exp_opcode opcode;
enum precedence myprec = PREC_NULL;
b = exp->elts[pc + 1].block;
if (b != NULL
&& BLOCK_FUNCTION (b) != NULL
- && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)) != NULL)
+ && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)) != NULL)
{
- fputs_filtered (SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)), stream);
+ fputs_filtered (SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)), stream);
fputs_filtered ("::", stream);
}
- fputs_filtered (SYMBOL_SOURCE_NAME (exp->elts[pc + 2].symbol), stream);
+ fputs_filtered (SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol), stream);
}
return;
return;
case OP_REGISTER:
- (*pos) += 2;
- fprintf_filtered (stream, "$%s",
- REGISTER_NAME (longest_to_int (exp->elts[pc + 1].longconst)));
- return;
+ {
+ int regnum = longest_to_int (exp->elts[pc + 1].longconst);
+ const char *name = user_reg_map_regnum_to_name (current_gdbarch,
+ regnum);
+ (*pos) += 2;
+ fprintf_filtered (stream, "$%s", name);
+ return;
+ }
case OP_BOOL:
(*pos) += 2;
fprintf_unfiltered (stream, "B'<unimplemented>'");
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);
+ 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, "[");
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
+ if (0 == target_read_string (exp->elts[pc + 1].longconst,
+ &selector, 1024, NULL))
+ {
+ error (_("bad selector"));
+ return;
+ }
+ if (nargs)
+ {
+ char *s, *nextS;
+ s = alloca (strlen (selector) + 1);
+ strcpy (s, selector);
+ for (tem = 0; tem < nargs; tem++)
+ {
+ nextS = strchr (s, ':');
+ *nextS = '\0';
+ fprintf_unfiltered (stream, " %s: ", s);
+ s = nextS + 1;
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+ }
+ }
+ else
+ {
+ fprintf_unfiltered (stream, " %s", selector);
+ }
+ fprintf_unfiltered (stream, "]");
+ /* "selector" was malloc'd by target_read_string. Free it. */
+ xfree (selector);
+ return;
+ }
+
case OP_ARRAY:
(*pos) += 3;
nargs = longest_to_int (exp->elts[pc + 2].longconst);
}
else
{
- /* OBSOLETE int is_chill = exp->language_defn->la_language == language_chill; */
- /* OBSOLETE fputs_filtered (is_chill ? " [" : " {", stream); */
fputs_filtered (" {", stream);
for (tem = 0; tem < nargs; tem++)
{
}
print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
}
- /* OBSOLETE fputs_filtered (is_chill ? "]" : "}", stream); */
fputs_filtered ("}", stream);
}
return;
case OP_LABELED:
tem = longest_to_int (exp->elts[pc + 1].longconst);
(*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-
-#if 0
- if (0 /* OBSOLETE exp->language_defn->la_language == language_chill */)
- { /* OBSOLETE */
- fputs_filtered (".", stream); /* OBSOLETE */
- fputs_filtered (&exp->elts[pc + 2].string, stream); /* OBSOLETE */
- fputs_filtered (exp->elts[*pos].opcode == OP_LABELED ? ", " /* OBSOLETE */
- : ": ", /* OBSOLETE */
- stream); /* OBSOLETE */
- } /* OBSOLETE */
- else /* OBSOLETE */
-#endif
- {
- /* Gcc support both these syntaxes. Unsure which is preferred. */
+ /* Gcc support both these syntaxes. Unsure which is preferred. */
#if 1
- fputs_filtered (&exp->elts[pc + 2].string, stream);
- fputs_filtered (": ", stream);
+ 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);
+ fputs_filtered (".", stream);
+ fputs_filtered (&exp->elts[pc + 2].string, stream);
+ fputs_filtered ("=", stream);
#endif
- }
print_subexp (exp, pos, stream, PREC_SUFFIX);
return;
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);
+ (CORE_ADDR) exp->elts[pc + 5].longconst);
value_print (val, stream, 0, Val_no_prettyprint);
}
else
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 */
fputs_filtered ("this", stream);
return;
+ /* Objective-C ops */
+
+ case OP_OBJC_SELF:
+ ++(*pos);
+ fputs_filtered ("self", stream); /* The ObjC equivalent of "this". */
+ return;
+
/* Modula-2 ops */
case MULTI_SUBSCRIPT:
case BINOP_INCL:
case BINOP_EXCL:
- error ("print_subexp: Not implemented.");
+ error (_("print_subexp: Not implemented."));
/* Default ops */
/* 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. */
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++)
/* Support for dumping the raw data from expressions in a human readable
form. */
-static char *op_name (int opcode);
+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 (int opcode)
+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)
{
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:
}
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;
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",
exp->language_defn->la_name, exp->nelts,
(long) sizeof (union exp_element));
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);
}
}
-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;
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);
- switch (exp->elts[elt++].opcode)
+ 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:
fprintf_filtered (stream, ", symbol @");
gdb_print_host_address (exp->elts[elt + 1].symbol, stream);
fprintf_filtered (stream, " (%s)",
- SYMBOL_NAME (exp->elts[elt + 1].symbol));
+ DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol));
elt += 3;
break;
case OP_LAST:
break;
case OP_FUNCALL:
{
- int nargs;
+ int i, nargs;
nargs = longest_to_int (exp->elts[elt].longconst);
fprintf_filtered (stream, "Unknown format");
}
- indent -= 2;
-
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);
- fprintf_filtered (stream, ", %s:\nExpression: `", note);
+ fputs_filtered (", after conversion to prefix form:\nExpression: `", stream);
if (exp->elts[0].opcode != OP_TYPE)
print_expression (exp, stream);
else