/* 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, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2003, 2007 Free Software Foundation, Inc.
This file is part of GDB.
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. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "symtab.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 "gdb_string.h"
#include "block.h"
+#include "objfiles.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;
case OP_REGISTER:
{
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", frame_map_regnum_to_name (regnum));
+ fprintf_filtered (stream, "$%s", name);
return;
}
if (0 == target_read_string (exp->elts[pc + 1].longconst,
&selector, 1024, NULL))
{
- error ("bad selector");
+ error (_("bad selector"));
return;
}
if (nargs)
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);
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
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;
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 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 "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:
}
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));
- switch (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 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:
break;
case OP_FUNCALL:
{
- int nargs;
+ int i, nargs;
nargs = longest_to_int (exp->elts[elt].longconst);
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);
break;
default:
case OP_NULL:
- case STRUCTOP_MEMBER:
- case STRUCTOP_MPTR:
case MULTI_SUBSCRIPT:
case OP_F77_UNDETERMINED_ARGLIST:
case OP_COMPLEX:
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