X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fexpprint.c;h=6f1fcbfe92ea6cd362d691b42a9d09ed56959041;hb=9c1b5f1b84b4e01424486ff95b30a2a13fd1b08d;hp=fadb0b76d1862d8a234aa058166c27f6a5d7275b;hpb=ed288bb597072176e84fc8279707a3f2f475779b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/expprint.c b/gdb/expprint.c index fadb0b76d1..6f1fcbfe92 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -1,11 +1,13 @@ /* Print in infix form a struct expression. - Copyright (C) 1986, 1989, 1991 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. 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, @@ -14,9 +16,7 @@ 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 . */ #include "defs.h" #include "symtab.h" @@ -25,20 +25,19 @@ #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" +#include "objfiles.h" +#include "gdb_assert.h" #ifdef HAVE_CTYPE_H #include #endif -/* Prototypes for local functions */ - -static void -print_subexp PARAMS ((struct expression *, int *, GDB_FILE *, enum precedence)); - void -print_expression (exp, stream) - struct expression *exp; - GDB_FILE *stream; +print_expression (struct expression *exp, struct ui_file *stream) { int pc = 0; print_subexp (exp, &pc, stream, PREC_NULL); @@ -49,24 +48,30 @@ print_expression (exp, stream) if the precedence of the main operator of this subexpression is less, parentheses are needed here. */ -static void -print_subexp (exp, pos, stream, prec) - register struct expression *exp; - register int *pos; - GDB_FILE *stream; - enum precedence prec; +void +print_subexp (struct expression *exp, int *pos, + struct ui_file *stream, enum precedence prec) +{ + 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) { - register unsigned tem; - register const struct op_print *op_print_tab; - register int pc; + 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; /* Set to 1 for a right-associative operator. */ int assoc = 0; - value_ptr val; + struct value *val; char *tempstr = NULL; op_print_tab = exp->language_defn->la_op_print_tab; @@ -107,12 +112,12 @@ print_subexp (exp, pos, stream, prec) 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; @@ -123,10 +128,12 @@ print_subexp (exp, pos, stream, prec) return; case OP_REGISTER: - (*pos) += 2; - fprintf_filtered (stream, "$%s", - REGISTER_NAME (longest_to_int (exp->elts[pc + 1].longconst))); - return; + { + 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; + } case OP_BOOL: (*pos) += 2; @@ -156,7 +163,6 @@ print_subexp (exp, pos, stream, prec) 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); @@ -178,6 +184,52 @@ print_subexp (exp, pos, stream, prec) fprintf_unfiltered (stream, "B''"); 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, ':'); + gdb_assert (nextS); /* Make sure we found ':'. */ + *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); @@ -221,8 +273,7 @@ print_subexp (exp, pos, stream, prec) } else { - int is_chill = exp->language_defn->la_language == language_chill; - fputs_filtered (is_chill ? " [" : " {", stream); + fputs_filtered (" {", stream); for (tem = 0; tem < nargs; tem++) { if (tem != 0) @@ -231,34 +282,22 @@ print_subexp (exp, pos, stream, prec) } print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); } - 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 (exp->language_defn->la_language == language_chill) - { - fputs_filtered (".", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - fputs_filtered (exp->elts[*pos].opcode == OP_LABELED ? ", " - : ": ", - stream); - } - else - { - /* 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; @@ -305,6 +344,18 @@ print_subexp (exp, pos, stream, prec) 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); @@ -338,7 +389,7 @@ print_subexp (exp, pos, stream, prec) (*pos) += 2; if ((int) prec > (int) PREC_PREFIX) fputs_filtered ("(", stream); - if (exp->elts[pc + 1].type->code == TYPE_CODE_FUNC && + if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC && exp->elts[pc + 3].opcode == OP_LONG) { /* We have a minimal symbol fn, probably. It's encoded @@ -347,8 +398,7 @@ print_subexp (exp, pos, stream, prec) 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 @@ -362,6 +412,18 @@ print_subexp (exp, pos, stream, prec) 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; @@ -378,7 +440,7 @@ print_subexp (exp, pos, stream, prec) 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 */ @@ -388,6 +450,13 @@ print_subexp (exp, pos, stream, prec) 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: @@ -415,7 +484,7 @@ print_subexp (exp, pos, stream, prec) case BINOP_INCL: case BINOP_EXCL: - error ("print_subexp: Not implemented."); + error (_("print_subexp: Not implemented.")); /* Default ops */ @@ -433,7 +502,7 @@ print_subexp (exp, pos, stream, prec) /* 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. */ @@ -488,11 +557,10 @@ print_subexp (exp, pos, stream, prec) a string. NULL indicates that the opcode was not found in the current language table. */ char * -op_string (op) - enum exp_opcode op; +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++) @@ -504,11 +572,22 @@ op_string (op) /* Support for dumping the raw data from expressions in a human readable form. */ -static char *op_name PARAMS ((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 (opcode) - 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) { @@ -575,8 +654,6 @@ op_name (opcode) return "BINOP_MIN"; case BINOP_MAX: return "BINOP_MAX"; - case BINOP_SCOPE: - return "BINOP_SCOPE"; case STRUCTOP_MEMBER: return "STRUCTOP_MEMBER"; case STRUCTOP_MPTR: @@ -627,6 +704,8 @@ op_name (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: @@ -685,6 +764,8 @@ op_name (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: @@ -695,10 +776,8 @@ op_name (opcode) } void -dump_prefix_expression (exp, stream, note) - struct expression *exp; - GDB_FILE *stream; - char *note; +dump_raw_expression (struct expression *exp, struct ui_file *stream, + char *note) { int elt; char *opcode_name; @@ -706,21 +785,16 @@ dump_prefix_expression (exp, stream, note) int eltsize; fprintf_filtered (stream, "Dump of expression @ "); - gdb_print_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, %d bytes each.\n", + 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, - sizeof (union exp_element)); + (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->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); @@ -738,13 +812,12 @@ dump_prefix_expression (exp, stream, note) } } -static int dump_subexp PARAMS ((struct expression * exp, GDB_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 -dump_subexp (exp, stream, elt) - struct expression *exp; - GDB_FILE *stream; - int elt; +int +dump_subexp (struct expression *exp, struct ui_file *stream, int elt) { static int indent = 0; int i; @@ -756,9 +829,34 @@ dump_subexp (exp, stream, elt) 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); +} + +/* 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 (exp->elts[elt++].opcode) + switch (opcode) { case TERNOP_COND: case TERNOP_SLICE: @@ -790,7 +888,6 @@ dump_subexp (exp, stream, elt) case BINOP_EXP: case BINOP_MIN: case BINOP_MAX: - case BINOP_SCOPE: case BINOP_INTDIV: case BINOP_ASSIGN_MODIFY: case BINOP_VAL: @@ -800,6 +897,8 @@ dump_subexp (exp, stream, elt) 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: @@ -831,7 +930,9 @@ dump_subexp (exp, stream, elt) elt = dump_subexp (exp, stream, elt); break; case OP_LONG: - fprintf_filtered (stream, "Type @0x%x (", exp->elts[elt].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, "), value %ld (0x%lx)", (long) exp->elts[elt + 1].longconst, @@ -839,17 +940,21 @@ dump_subexp (exp, stream, elt) elt += 3; break; case OP_DOUBLE: - fprintf_filtered (stream, "Type @0x%x (", exp->elts[elt].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, "), value %g", (double) exp->elts[elt + 1].doubleconst); elt += 3; break; case OP_VAR_VALUE: - fprintf_filtered (stream, "Block @0x%x, symbol @0x%x (%s)", - exp->elts[elt].block, - exp->elts[elt + 1].symbol, - SYMBOL_NAME (exp->elts[elt + 1].symbol)); + 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)", + DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol)); elt += 3; break; case OP_LAST: @@ -858,19 +963,19 @@ dump_subexp (exp, stream, elt) 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 @0x%x (%s)", - exp->elts[elt].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 nargs; + int i, nargs; nargs = longest_to_int (exp->elts[elt].longconst); @@ -898,15 +1003,27 @@ dump_subexp (exp, stream, elt) break; case UNOP_MEMVAL: case UNOP_CAST: - fprintf_filtered (stream, "Type @0x%x (", - exp->elts[elt].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 = 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 @0x%x (", - exp->elts[elt].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; @@ -929,7 +1046,9 @@ dump_subexp (exp, stream, elt) char *elem_name; int len; - fprintf_filtered (stream, "Type @0x%x (", exp->elts[elt].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, ") "); @@ -942,8 +1061,6 @@ dump_subexp (exp, stream, elt) break; default: case OP_NULL: - case STRUCTOP_MEMBER: - case STRUCTOP_MPTR: case MULTI_SUBSCRIPT: case OP_F77_UNDETERMINED_ARGLIST: case OP_COMPLEX: @@ -954,33 +1071,27 @@ dump_subexp (exp, stream, elt) case OP_THIS: case OP_LABELED: case OP_NAME: - case OP_EXPRSTRING: fprintf_filtered (stream, "Unknown format"); } - indent -= 2; - return elt; } void -dump_postfix_expression (exp, stream, note) - struct expression *exp; - GDB_FILE *stream; - char *note; +dump_prefix_expression (struct expression *exp, struct ui_file *stream) { int elt; fprintf_filtered (stream, "Dump of expression @ "); - gdb_print_address (exp, stream); - fprintf_filtered (stream, ", %s:\nExpression: `", note); + 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, %d bytes each.\n", + fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n", exp->language_defn->la_name, exp->nelts, - sizeof (union exp_element)); + (long) sizeof (union exp_element)); fputs_filtered ("\n", stream); for (elt = 0; elt < exp->nelts;)