GDB (API)
|
00001 /* Print in infix form a struct expression. 00002 00003 Copyright (C) 1986-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "symtab.h" 00022 #include "gdbtypes.h" 00023 #include "expression.h" 00024 #include "value.h" 00025 #include "language.h" 00026 #include "parser-defs.h" 00027 #include "user-regs.h" /* For user_reg_map_regnum_to_name. */ 00028 #include "target.h" 00029 #include "gdb_string.h" 00030 #include "block.h" 00031 #include "objfiles.h" 00032 #include "gdb_assert.h" 00033 #include "valprint.h" 00034 00035 #include <ctype.h> 00036 00037 void 00038 print_expression (struct expression *exp, struct ui_file *stream) 00039 { 00040 int pc = 0; 00041 00042 print_subexp (exp, &pc, stream, PREC_NULL); 00043 } 00044 00045 /* Print the subexpression of EXP that starts in position POS, on STREAM. 00046 PREC is the precedence of the surrounding operator; 00047 if the precedence of the main operator of this subexpression is less, 00048 parentheses are needed here. */ 00049 00050 void 00051 print_subexp (struct expression *exp, int *pos, 00052 struct ui_file *stream, enum precedence prec) 00053 { 00054 exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec); 00055 } 00056 00057 /* Standard implementation of print_subexp for use in language_defn 00058 vectors. */ 00059 void 00060 print_subexp_standard (struct expression *exp, int *pos, 00061 struct ui_file *stream, enum precedence prec) 00062 { 00063 unsigned tem; 00064 const struct op_print *op_print_tab; 00065 int pc; 00066 unsigned nargs; 00067 char *op_str; 00068 int assign_modify = 0; 00069 enum exp_opcode opcode; 00070 enum precedence myprec = PREC_NULL; 00071 /* Set to 1 for a right-associative operator. */ 00072 int assoc = 0; 00073 struct value *val; 00074 char *tempstr = NULL; 00075 00076 op_print_tab = exp->language_defn->la_op_print_tab; 00077 pc = (*pos)++; 00078 opcode = exp->elts[pc].opcode; 00079 switch (opcode) 00080 { 00081 /* Common ops */ 00082 00083 case OP_TYPE: 00084 (*pos) += 2; 00085 type_print (exp->elts[pc + 1].type, "", stream, 0); 00086 return; 00087 00088 case OP_SCOPE: 00089 myprec = PREC_PREFIX; 00090 assoc = 0; 00091 fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream); 00092 fputs_filtered ("::", stream); 00093 nargs = longest_to_int (exp->elts[pc + 2].longconst); 00094 (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1); 00095 fputs_filtered (&exp->elts[pc + 3].string, stream); 00096 return; 00097 00098 case OP_LONG: 00099 { 00100 struct value_print_options opts; 00101 00102 get_no_prettyformat_print_options (&opts); 00103 (*pos) += 3; 00104 value_print (value_from_longest (exp->elts[pc + 1].type, 00105 exp->elts[pc + 2].longconst), 00106 stream, &opts); 00107 } 00108 return; 00109 00110 case OP_DOUBLE: 00111 { 00112 struct value_print_options opts; 00113 00114 get_no_prettyformat_print_options (&opts); 00115 (*pos) += 3; 00116 value_print (value_from_double (exp->elts[pc + 1].type, 00117 exp->elts[pc + 2].doubleconst), 00118 stream, &opts); 00119 } 00120 return; 00121 00122 case OP_VAR_VALUE: 00123 { 00124 const struct block *b; 00125 00126 (*pos) += 3; 00127 b = exp->elts[pc + 1].block; 00128 if (b != NULL 00129 && BLOCK_FUNCTION (b) != NULL 00130 && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)) != NULL) 00131 { 00132 fputs_filtered (SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)), stream); 00133 fputs_filtered ("::", stream); 00134 } 00135 fputs_filtered (SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol), stream); 00136 } 00137 return; 00138 00139 case OP_VAR_ENTRY_VALUE: 00140 { 00141 (*pos) += 2; 00142 fprintf_filtered (stream, "%s@entry", 00143 SYMBOL_PRINT_NAME (exp->elts[pc + 1].symbol)); 00144 } 00145 return; 00146 00147 case OP_LAST: 00148 (*pos) += 2; 00149 fprintf_filtered (stream, "$%d", 00150 longest_to_int (exp->elts[pc + 1].longconst)); 00151 return; 00152 00153 case OP_REGISTER: 00154 { 00155 const char *name = &exp->elts[pc + 2].string; 00156 00157 (*pos) += 3 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1); 00158 fprintf_filtered (stream, "$%s", name); 00159 return; 00160 } 00161 00162 case OP_BOOL: 00163 (*pos) += 2; 00164 fprintf_filtered (stream, "%s", 00165 longest_to_int (exp->elts[pc + 1].longconst) 00166 ? "TRUE" : "FALSE"); 00167 return; 00168 00169 case OP_INTERNALVAR: 00170 (*pos) += 2; 00171 fprintf_filtered (stream, "$%s", 00172 internalvar_name (exp->elts[pc + 1].internalvar)); 00173 return; 00174 00175 case OP_FUNCALL: 00176 (*pos) += 2; 00177 nargs = longest_to_int (exp->elts[pc + 1].longconst); 00178 print_subexp (exp, pos, stream, PREC_SUFFIX); 00179 fputs_filtered (" (", stream); 00180 for (tem = 0; tem < nargs; tem++) 00181 { 00182 if (tem != 0) 00183 fputs_filtered (", ", stream); 00184 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00185 } 00186 fputs_filtered (")", stream); 00187 return; 00188 00189 case OP_NAME: 00190 nargs = longest_to_int (exp->elts[pc + 1].longconst); 00191 (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); 00192 fputs_filtered (&exp->elts[pc + 2].string, stream); 00193 return; 00194 00195 case OP_STRING: 00196 { 00197 struct value_print_options opts; 00198 00199 nargs = longest_to_int (exp->elts[pc + 1].longconst); 00200 (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); 00201 /* LA_PRINT_STRING will print using the current repeat count threshold. 00202 If necessary, we can temporarily set it to zero, or pass it as an 00203 additional parameter to LA_PRINT_STRING. -fnf */ 00204 get_user_print_options (&opts); 00205 LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char, 00206 (gdb_byte *) &exp->elts[pc + 2].string, nargs, 00207 NULL, 0, &opts); 00208 } 00209 return; 00210 00211 case OP_OBJC_NSSTRING: /* Objective-C Foundation Class 00212 NSString constant. */ 00213 { 00214 struct value_print_options opts; 00215 00216 nargs = longest_to_int (exp->elts[pc + 1].longconst); 00217 (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); 00218 fputs_filtered ("@\"", stream); 00219 get_user_print_options (&opts); 00220 LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char, 00221 (gdb_byte *) &exp->elts[pc + 2].string, nargs, 00222 NULL, 0, &opts); 00223 fputs_filtered ("\"", stream); 00224 } 00225 return; 00226 00227 case OP_OBJC_MSGCALL: 00228 { /* Objective C message (method) call. */ 00229 char *selector; 00230 00231 (*pos) += 3; 00232 nargs = longest_to_int (exp->elts[pc + 2].longconst); 00233 fprintf_unfiltered (stream, "["); 00234 print_subexp (exp, pos, stream, PREC_SUFFIX); 00235 if (0 == target_read_string (exp->elts[pc + 1].longconst, 00236 &selector, 1024, NULL)) 00237 { 00238 error (_("bad selector")); 00239 return; 00240 } 00241 if (nargs) 00242 { 00243 char *s, *nextS; 00244 00245 s = alloca (strlen (selector) + 1); 00246 strcpy (s, selector); 00247 for (tem = 0; tem < nargs; tem++) 00248 { 00249 nextS = strchr (s, ':'); 00250 gdb_assert (nextS); /* Make sure we found ':'. */ 00251 *nextS = '\0'; 00252 fprintf_unfiltered (stream, " %s: ", s); 00253 s = nextS + 1; 00254 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00255 } 00256 } 00257 else 00258 { 00259 fprintf_unfiltered (stream, " %s", selector); 00260 } 00261 fprintf_unfiltered (stream, "]"); 00262 /* "selector" was malloc'd by target_read_string. Free it. */ 00263 xfree (selector); 00264 return; 00265 } 00266 00267 case OP_ARRAY: 00268 (*pos) += 3; 00269 nargs = longest_to_int (exp->elts[pc + 2].longconst); 00270 nargs -= longest_to_int (exp->elts[pc + 1].longconst); 00271 nargs++; 00272 tem = 0; 00273 if (exp->elts[pc + 4].opcode == OP_LONG 00274 && exp->elts[pc + 5].type 00275 == builtin_type (exp->gdbarch)->builtin_char 00276 && exp->language_defn->la_language == language_c) 00277 { 00278 /* Attempt to print C character arrays using string syntax. 00279 Walk through the args, picking up one character from each 00280 of the OP_LONG expression elements. If any array element 00281 does not match our expection of what we should find for 00282 a simple string, revert back to array printing. Note that 00283 the last expression element is an explicit null terminator 00284 byte, which doesn't get printed. */ 00285 tempstr = alloca (nargs); 00286 pc += 4; 00287 while (tem < nargs) 00288 { 00289 if (exp->elts[pc].opcode != OP_LONG 00290 || exp->elts[pc + 1].type 00291 != builtin_type (exp->gdbarch)->builtin_char) 00292 { 00293 /* Not a simple array of char, use regular array 00294 printing. */ 00295 tem = 0; 00296 break; 00297 } 00298 else 00299 { 00300 tempstr[tem++] = 00301 longest_to_int (exp->elts[pc + 2].longconst); 00302 pc += 4; 00303 } 00304 } 00305 } 00306 if (tem > 0) 00307 { 00308 struct value_print_options opts; 00309 00310 get_user_print_options (&opts); 00311 LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char, 00312 (gdb_byte *) tempstr, nargs - 1, NULL, 0, &opts); 00313 (*pos) = pc; 00314 } 00315 else 00316 { 00317 fputs_filtered (" {", stream); 00318 for (tem = 0; tem < nargs; tem++) 00319 { 00320 if (tem != 0) 00321 { 00322 fputs_filtered (", ", stream); 00323 } 00324 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00325 } 00326 fputs_filtered ("}", stream); 00327 } 00328 return; 00329 00330 case TERNOP_COND: 00331 if ((int) prec > (int) PREC_COMMA) 00332 fputs_filtered ("(", stream); 00333 /* Print the subexpressions, forcing parentheses 00334 around any binary operations within them. 00335 This is more parentheses than are strictly necessary, 00336 but it looks clearer. */ 00337 print_subexp (exp, pos, stream, PREC_HYPER); 00338 fputs_filtered (" ? ", stream); 00339 print_subexp (exp, pos, stream, PREC_HYPER); 00340 fputs_filtered (" : ", stream); 00341 print_subexp (exp, pos, stream, PREC_HYPER); 00342 if ((int) prec > (int) PREC_COMMA) 00343 fputs_filtered (")", stream); 00344 return; 00345 00346 case TERNOP_SLICE: 00347 print_subexp (exp, pos, stream, PREC_SUFFIX); 00348 fputs_filtered ("(", stream); 00349 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00350 fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream); 00351 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00352 fputs_filtered (")", stream); 00353 return; 00354 00355 case STRUCTOP_STRUCT: 00356 tem = longest_to_int (exp->elts[pc + 1].longconst); 00357 (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); 00358 print_subexp (exp, pos, stream, PREC_SUFFIX); 00359 fputs_filtered (".", stream); 00360 fputs_filtered (&exp->elts[pc + 2].string, stream); 00361 return; 00362 00363 /* Will not occur for Modula-2. */ 00364 case STRUCTOP_PTR: 00365 tem = longest_to_int (exp->elts[pc + 1].longconst); 00366 (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); 00367 print_subexp (exp, pos, stream, PREC_SUFFIX); 00368 fputs_filtered ("->", stream); 00369 fputs_filtered (&exp->elts[pc + 2].string, stream); 00370 return; 00371 00372 case STRUCTOP_MEMBER: 00373 print_subexp (exp, pos, stream, PREC_SUFFIX); 00374 fputs_filtered (".*", stream); 00375 print_subexp (exp, pos, stream, PREC_SUFFIX); 00376 return; 00377 00378 case STRUCTOP_MPTR: 00379 print_subexp (exp, pos, stream, PREC_SUFFIX); 00380 fputs_filtered ("->*", stream); 00381 print_subexp (exp, pos, stream, PREC_SUFFIX); 00382 return; 00383 00384 case BINOP_SUBSCRIPT: 00385 print_subexp (exp, pos, stream, PREC_SUFFIX); 00386 fputs_filtered ("[", stream); 00387 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00388 fputs_filtered ("]", stream); 00389 return; 00390 00391 case UNOP_POSTINCREMENT: 00392 print_subexp (exp, pos, stream, PREC_SUFFIX); 00393 fputs_filtered ("++", stream); 00394 return; 00395 00396 case UNOP_POSTDECREMENT: 00397 print_subexp (exp, pos, stream, PREC_SUFFIX); 00398 fputs_filtered ("--", stream); 00399 return; 00400 00401 case UNOP_CAST: 00402 (*pos) += 2; 00403 if ((int) prec > (int) PREC_PREFIX) 00404 fputs_filtered ("(", stream); 00405 fputs_filtered ("(", stream); 00406 type_print (exp->elts[pc + 1].type, "", stream, 0); 00407 fputs_filtered (") ", stream); 00408 print_subexp (exp, pos, stream, PREC_PREFIX); 00409 if ((int) prec > (int) PREC_PREFIX) 00410 fputs_filtered (")", stream); 00411 return; 00412 00413 case UNOP_CAST_TYPE: 00414 if ((int) prec > (int) PREC_PREFIX) 00415 fputs_filtered ("(", stream); 00416 fputs_filtered ("(", stream); 00417 print_subexp (exp, pos, stream, PREC_PREFIX); 00418 fputs_filtered (") ", stream); 00419 print_subexp (exp, pos, stream, PREC_PREFIX); 00420 if ((int) prec > (int) PREC_PREFIX) 00421 fputs_filtered (")", stream); 00422 return; 00423 00424 case UNOP_DYNAMIC_CAST: 00425 case UNOP_REINTERPRET_CAST: 00426 fputs_filtered (opcode == UNOP_DYNAMIC_CAST ? "dynamic_cast" 00427 : "reinterpret_cast", stream); 00428 fputs_filtered ("<", stream); 00429 print_subexp (exp, pos, stream, PREC_PREFIX); 00430 fputs_filtered ("> (", stream); 00431 print_subexp (exp, pos, stream, PREC_PREFIX); 00432 fputs_filtered (")", stream); 00433 return; 00434 00435 case UNOP_MEMVAL: 00436 (*pos) += 2; 00437 if ((int) prec > (int) PREC_PREFIX) 00438 fputs_filtered ("(", stream); 00439 if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC 00440 && exp->elts[pc + 3].opcode == OP_LONG) 00441 { 00442 struct value_print_options opts; 00443 00444 /* We have a minimal symbol fn, probably. It's encoded 00445 as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address). 00446 Swallow the OP_LONG (including both its opcodes); ignore 00447 its type; print the value in the type of the MEMVAL. */ 00448 (*pos) += 4; 00449 val = value_at_lazy (exp->elts[pc + 1].type, 00450 (CORE_ADDR) exp->elts[pc + 5].longconst); 00451 get_no_prettyformat_print_options (&opts); 00452 value_print (val, stream, &opts); 00453 } 00454 else 00455 { 00456 fputs_filtered ("{", stream); 00457 type_print (exp->elts[pc + 1].type, "", stream, 0); 00458 fputs_filtered ("} ", stream); 00459 print_subexp (exp, pos, stream, PREC_PREFIX); 00460 } 00461 if ((int) prec > (int) PREC_PREFIX) 00462 fputs_filtered (")", stream); 00463 return; 00464 00465 case UNOP_MEMVAL_TYPE: 00466 if ((int) prec > (int) PREC_PREFIX) 00467 fputs_filtered ("(", stream); 00468 fputs_filtered ("{", stream); 00469 print_subexp (exp, pos, stream, PREC_PREFIX); 00470 fputs_filtered ("} ", stream); 00471 print_subexp (exp, pos, stream, PREC_PREFIX); 00472 if ((int) prec > (int) PREC_PREFIX) 00473 fputs_filtered (")", stream); 00474 return; 00475 00476 case UNOP_MEMVAL_TLS: 00477 (*pos) += 3; 00478 if ((int) prec > (int) PREC_PREFIX) 00479 fputs_filtered ("(", stream); 00480 fputs_filtered ("{", stream); 00481 type_print (exp->elts[pc + 2].type, "", stream, 0); 00482 fputs_filtered ("} ", stream); 00483 print_subexp (exp, pos, stream, PREC_PREFIX); 00484 if ((int) prec > (int) PREC_PREFIX) 00485 fputs_filtered (")", stream); 00486 return; 00487 00488 case BINOP_ASSIGN_MODIFY: 00489 opcode = exp->elts[pc + 1].opcode; 00490 (*pos) += 2; 00491 myprec = PREC_ASSIGN; 00492 assoc = 1; 00493 assign_modify = 1; 00494 op_str = "???"; 00495 for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) 00496 if (op_print_tab[tem].opcode == opcode) 00497 { 00498 op_str = op_print_tab[tem].string; 00499 break; 00500 } 00501 if (op_print_tab[tem].opcode != opcode) 00502 /* Not found; don't try to keep going because we don't know how 00503 to interpret further elements. */ 00504 error (_("Invalid expression")); 00505 break; 00506 00507 /* C++ ops */ 00508 00509 case OP_THIS: 00510 ++(*pos); 00511 if (exp->language_defn->la_name_of_this) 00512 fputs_filtered (exp->language_defn->la_name_of_this, stream); 00513 else 00514 fprintf_filtered (stream, _("<language %s has no 'this'>"), 00515 exp->language_defn->la_name); 00516 return; 00517 00518 /* Modula-2 ops */ 00519 00520 case MULTI_SUBSCRIPT: 00521 (*pos) += 2; 00522 nargs = longest_to_int (exp->elts[pc + 1].longconst); 00523 print_subexp (exp, pos, stream, PREC_SUFFIX); 00524 fprintf_unfiltered (stream, " ["); 00525 for (tem = 0; tem < nargs; tem++) 00526 { 00527 if (tem != 0) 00528 fprintf_unfiltered (stream, ", "); 00529 print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); 00530 } 00531 fprintf_unfiltered (stream, "]"); 00532 return; 00533 00534 case BINOP_VAL: 00535 (*pos) += 2; 00536 fprintf_unfiltered (stream, "VAL("); 00537 type_print (exp->elts[pc + 1].type, "", stream, 0); 00538 fprintf_unfiltered (stream, ","); 00539 print_subexp (exp, pos, stream, PREC_PREFIX); 00540 fprintf_unfiltered (stream, ")"); 00541 return; 00542 00543 case TYPE_INSTANCE: 00544 { 00545 LONGEST count = exp->elts[pc + 1].longconst; 00546 00547 /* The COUNT. */ 00548 (*pos)++; 00549 fputs_unfiltered ("TypesInstance(", stream); 00550 while (count-- > 0) 00551 { 00552 type_print (exp->elts[(*pos)++].type, "", stream, 0); 00553 if (count > 0) 00554 fputs_unfiltered (",", stream); 00555 } 00556 fputs_unfiltered (",", stream); 00557 /* Ending COUNT and ending TYPE_INSTANCE. */ 00558 (*pos) += 2; 00559 print_subexp (exp, pos, stream, PREC_PREFIX); 00560 fputs_unfiltered (")", stream); 00561 return; 00562 } 00563 00564 /* Default ops */ 00565 00566 default: 00567 op_str = "???"; 00568 for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) 00569 if (op_print_tab[tem].opcode == opcode) 00570 { 00571 op_str = op_print_tab[tem].string; 00572 myprec = op_print_tab[tem].precedence; 00573 assoc = op_print_tab[tem].right_assoc; 00574 break; 00575 } 00576 if (op_print_tab[tem].opcode != opcode) 00577 /* Not found; don't try to keep going because we don't know how 00578 to interpret further elements. For example, this happens 00579 if opcode is OP_TYPE. */ 00580 error (_("Invalid expression")); 00581 } 00582 00583 /* Note that PREC_BUILTIN will always emit parentheses. */ 00584 if ((int) myprec < (int) prec) 00585 fputs_filtered ("(", stream); 00586 if ((int) opcode > (int) BINOP_END) 00587 { 00588 if (assoc) 00589 { 00590 /* Unary postfix operator. */ 00591 print_subexp (exp, pos, stream, PREC_SUFFIX); 00592 fputs_filtered (op_str, stream); 00593 } 00594 else 00595 { 00596 /* Unary prefix operator. */ 00597 fputs_filtered (op_str, stream); 00598 if (myprec == PREC_BUILTIN_FUNCTION) 00599 fputs_filtered ("(", stream); 00600 print_subexp (exp, pos, stream, PREC_PREFIX); 00601 if (myprec == PREC_BUILTIN_FUNCTION) 00602 fputs_filtered (")", stream); 00603 } 00604 } 00605 else 00606 { 00607 /* Binary operator. */ 00608 /* Print left operand. 00609 If operator is right-associative, 00610 increment precedence for this operand. */ 00611 print_subexp (exp, pos, stream, 00612 (enum precedence) ((int) myprec + assoc)); 00613 /* Print the operator itself. */ 00614 if (assign_modify) 00615 fprintf_filtered (stream, " %s= ", op_str); 00616 else if (op_str[0] == ',') 00617 fprintf_filtered (stream, "%s ", op_str); 00618 else 00619 fprintf_filtered (stream, " %s ", op_str); 00620 /* Print right operand. 00621 If operator is left-associative, 00622 increment precedence for this operand. */ 00623 print_subexp (exp, pos, stream, 00624 (enum precedence) ((int) myprec + !assoc)); 00625 } 00626 00627 if ((int) myprec < (int) prec) 00628 fputs_filtered (")", stream); 00629 } 00630 00631 /* Return the operator corresponding to opcode OP as 00632 a string. NULL indicates that the opcode was not found in the 00633 current language table. */ 00634 char * 00635 op_string (enum exp_opcode op) 00636 { 00637 int tem; 00638 const struct op_print *op_print_tab; 00639 00640 op_print_tab = current_language->la_op_print_tab; 00641 for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) 00642 if (op_print_tab[tem].opcode == op) 00643 return op_print_tab[tem].string; 00644 return NULL; 00645 } 00646 00647 /* Support for dumping the raw data from expressions in a human readable 00648 form. */ 00649 00650 static int dump_subexp_body (struct expression *exp, struct ui_file *, int); 00651 00652 /* Name for OPCODE, when it appears in expression EXP. */ 00653 00654 char * 00655 op_name (struct expression *exp, enum exp_opcode opcode) 00656 { 00657 return exp->language_defn->la_exp_desc->op_name (opcode); 00658 } 00659 00660 /* Default name for the standard operator OPCODE (i.e., one defined in 00661 the definition of enum exp_opcode). */ 00662 00663 char * 00664 op_name_standard (enum exp_opcode opcode) 00665 { 00666 switch (opcode) 00667 { 00668 default: 00669 { 00670 static char buf[30]; 00671 00672 xsnprintf (buf, sizeof (buf), "<unknown %d>", opcode); 00673 return buf; 00674 } 00675 #define OP(name) \ 00676 case name: \ 00677 return #name ; 00678 #include "std-operator.def" 00679 #undef OP 00680 } 00681 } 00682 00683 /* Print a raw dump of expression EXP to STREAM. 00684 NOTE, if non-NULL, is printed as extra explanatory text. */ 00685 00686 void 00687 dump_raw_expression (struct expression *exp, struct ui_file *stream, 00688 char *note) 00689 { 00690 int elt; 00691 char *opcode_name; 00692 char *eltscan; 00693 int eltsize; 00694 00695 fprintf_filtered (stream, "Dump of expression @ "); 00696 gdb_print_host_address (exp, stream); 00697 if (note) 00698 fprintf_filtered (stream, ", %s:", note); 00699 fprintf_filtered (stream, "\n\tLanguage %s, %d elements, %ld bytes each.\n", 00700 exp->language_defn->la_name, exp->nelts, 00701 (long) sizeof (union exp_element)); 00702 fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode", 00703 "Hex Value", "String Value"); 00704 for (elt = 0; elt < exp->nelts; elt++) 00705 { 00706 fprintf_filtered (stream, "\t%5d ", elt); 00707 opcode_name = op_name (exp, exp->elts[elt].opcode); 00708 00709 fprintf_filtered (stream, "%20s ", opcode_name); 00710 print_longest (stream, 'd', 0, exp->elts[elt].longconst); 00711 fprintf_filtered (stream, " "); 00712 00713 for (eltscan = (char *) &exp->elts[elt], 00714 eltsize = sizeof (union exp_element); 00715 eltsize-- > 0; 00716 eltscan++) 00717 { 00718 fprintf_filtered (stream, "%c", 00719 isprint (*eltscan) ? (*eltscan & 0xFF) : '.'); 00720 } 00721 fprintf_filtered (stream, "\n"); 00722 } 00723 } 00724 00725 /* Dump the subexpression of prefix expression EXP whose operator is at 00726 position ELT onto STREAM. Returns the position of the next 00727 subexpression in EXP. */ 00728 00729 int 00730 dump_subexp (struct expression *exp, struct ui_file *stream, int elt) 00731 { 00732 static int indent = 0; 00733 int i; 00734 00735 fprintf_filtered (stream, "\n"); 00736 fprintf_filtered (stream, "\t%5d ", elt); 00737 00738 for (i = 1; i <= indent; i++) 00739 fprintf_filtered (stream, " "); 00740 indent += 2; 00741 00742 fprintf_filtered (stream, "%-20s ", op_name (exp, exp->elts[elt].opcode)); 00743 00744 elt = dump_subexp_body (exp, stream, elt); 00745 00746 indent -= 2; 00747 00748 return elt; 00749 } 00750 00751 /* Dump the operands of prefix expression EXP whose opcode is at 00752 position ELT onto STREAM. Returns the position of the next 00753 subexpression in EXP. */ 00754 00755 static int 00756 dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt) 00757 { 00758 return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt); 00759 } 00760 00761 /* Default value for subexp_body in exp_descriptor vector. */ 00762 00763 int 00764 dump_subexp_body_standard (struct expression *exp, 00765 struct ui_file *stream, int elt) 00766 { 00767 int opcode = exp->elts[elt++].opcode; 00768 00769 switch (opcode) 00770 { 00771 case TERNOP_COND: 00772 case TERNOP_SLICE: 00773 elt = dump_subexp (exp, stream, elt); 00774 /* FALL THROUGH */ 00775 case BINOP_ADD: 00776 case BINOP_SUB: 00777 case BINOP_MUL: 00778 case BINOP_DIV: 00779 case BINOP_REM: 00780 case BINOP_MOD: 00781 case BINOP_LSH: 00782 case BINOP_RSH: 00783 case BINOP_LOGICAL_AND: 00784 case BINOP_LOGICAL_OR: 00785 case BINOP_BITWISE_AND: 00786 case BINOP_BITWISE_IOR: 00787 case BINOP_BITWISE_XOR: 00788 case BINOP_EQUAL: 00789 case BINOP_NOTEQUAL: 00790 case BINOP_LESS: 00791 case BINOP_GTR: 00792 case BINOP_LEQ: 00793 case BINOP_GEQ: 00794 case BINOP_REPEAT: 00795 case BINOP_ASSIGN: 00796 case BINOP_COMMA: 00797 case BINOP_SUBSCRIPT: 00798 case BINOP_EXP: 00799 case BINOP_MIN: 00800 case BINOP_MAX: 00801 case BINOP_INTDIV: 00802 case BINOP_ASSIGN_MODIFY: 00803 case BINOP_VAL: 00804 case BINOP_CONCAT: 00805 case BINOP_IN: 00806 case BINOP_RANGE: 00807 case BINOP_END: 00808 case STRUCTOP_MEMBER: 00809 case STRUCTOP_MPTR: 00810 elt = dump_subexp (exp, stream, elt); 00811 /* FALL THROUGH */ 00812 case UNOP_NEG: 00813 case UNOP_LOGICAL_NOT: 00814 case UNOP_COMPLEMENT: 00815 case UNOP_IND: 00816 case UNOP_ADDR: 00817 case UNOP_PREINCREMENT: 00818 case UNOP_POSTINCREMENT: 00819 case UNOP_PREDECREMENT: 00820 case UNOP_POSTDECREMENT: 00821 case UNOP_SIZEOF: 00822 case UNOP_PLUS: 00823 case UNOP_CAP: 00824 case UNOP_CHR: 00825 case UNOP_ORD: 00826 case UNOP_ABS: 00827 case UNOP_FLOAT: 00828 case UNOP_HIGH: 00829 case UNOP_MAX: 00830 case UNOP_MIN: 00831 case UNOP_ODD: 00832 case UNOP_TRUNC: 00833 elt = dump_subexp (exp, stream, elt); 00834 break; 00835 case OP_LONG: 00836 fprintf_filtered (stream, "Type @"); 00837 gdb_print_host_address (exp->elts[elt].type, stream); 00838 fprintf_filtered (stream, " ("); 00839 type_print (exp->elts[elt].type, NULL, stream, 0); 00840 fprintf_filtered (stream, "), value %ld (0x%lx)", 00841 (long) exp->elts[elt + 1].longconst, 00842 (long) exp->elts[elt + 1].longconst); 00843 elt += 3; 00844 break; 00845 case OP_DOUBLE: 00846 fprintf_filtered (stream, "Type @"); 00847 gdb_print_host_address (exp->elts[elt].type, stream); 00848 fprintf_filtered (stream, " ("); 00849 type_print (exp->elts[elt].type, NULL, stream, 0); 00850 fprintf_filtered (stream, "), value %g", 00851 (double) exp->elts[elt + 1].doubleconst); 00852 elt += 3; 00853 break; 00854 case OP_VAR_VALUE: 00855 fprintf_filtered (stream, "Block @"); 00856 gdb_print_host_address (exp->elts[elt].block, stream); 00857 fprintf_filtered (stream, ", symbol @"); 00858 gdb_print_host_address (exp->elts[elt + 1].symbol, stream); 00859 fprintf_filtered (stream, " (%s)", 00860 SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol)); 00861 elt += 3; 00862 break; 00863 case OP_VAR_ENTRY_VALUE: 00864 fprintf_filtered (stream, "Entry value of symbol @"); 00865 gdb_print_host_address (exp->elts[elt].symbol, stream); 00866 fprintf_filtered (stream, " (%s)", 00867 SYMBOL_PRINT_NAME (exp->elts[elt].symbol)); 00868 elt += 2; 00869 break; 00870 case OP_LAST: 00871 fprintf_filtered (stream, "History element %ld", 00872 (long) exp->elts[elt].longconst); 00873 elt += 2; 00874 break; 00875 case OP_REGISTER: 00876 fprintf_filtered (stream, "Register $%s", &exp->elts[elt + 1].string); 00877 elt += 3 + BYTES_TO_EXP_ELEM (exp->elts[elt].longconst + 1); 00878 break; 00879 case OP_INTERNALVAR: 00880 fprintf_filtered (stream, "Internal var @"); 00881 gdb_print_host_address (exp->elts[elt].internalvar, stream); 00882 fprintf_filtered (stream, " (%s)", 00883 internalvar_name (exp->elts[elt].internalvar)); 00884 elt += 2; 00885 break; 00886 case OP_FUNCALL: 00887 { 00888 int i, nargs; 00889 00890 nargs = longest_to_int (exp->elts[elt].longconst); 00891 00892 fprintf_filtered (stream, "Number of args: %d", nargs); 00893 elt += 2; 00894 00895 for (i = 1; i <= nargs + 1; i++) 00896 elt = dump_subexp (exp, stream, elt); 00897 } 00898 break; 00899 case OP_ARRAY: 00900 { 00901 int lower, upper; 00902 int i; 00903 00904 lower = longest_to_int (exp->elts[elt].longconst); 00905 upper = longest_to_int (exp->elts[elt + 1].longconst); 00906 00907 fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper); 00908 elt += 3; 00909 00910 for (i = 1; i <= upper - lower + 1; i++) 00911 elt = dump_subexp (exp, stream, elt); 00912 } 00913 break; 00914 case UNOP_DYNAMIC_CAST: 00915 case UNOP_REINTERPRET_CAST: 00916 case UNOP_CAST_TYPE: 00917 case UNOP_MEMVAL_TYPE: 00918 fprintf_filtered (stream, " ("); 00919 elt = dump_subexp (exp, stream, elt); 00920 fprintf_filtered (stream, ")"); 00921 elt = dump_subexp (exp, stream, elt); 00922 break; 00923 case UNOP_MEMVAL: 00924 case UNOP_CAST: 00925 fprintf_filtered (stream, "Type @"); 00926 gdb_print_host_address (exp->elts[elt].type, stream); 00927 fprintf_filtered (stream, " ("); 00928 type_print (exp->elts[elt].type, NULL, stream, 0); 00929 fprintf_filtered (stream, ")"); 00930 elt = dump_subexp (exp, stream, elt + 2); 00931 break; 00932 case UNOP_MEMVAL_TLS: 00933 fprintf_filtered (stream, "TLS type @"); 00934 gdb_print_host_address (exp->elts[elt + 1].type, stream); 00935 fprintf_filtered (stream, " (__thread /* \"%s\" */ ", 00936 (exp->elts[elt].objfile == NULL ? "(null)" 00937 : objfile_name (exp->elts[elt].objfile))); 00938 type_print (exp->elts[elt + 1].type, NULL, stream, 0); 00939 fprintf_filtered (stream, ")"); 00940 elt = dump_subexp (exp, stream, elt + 3); 00941 break; 00942 case OP_TYPE: 00943 fprintf_filtered (stream, "Type @"); 00944 gdb_print_host_address (exp->elts[elt].type, stream); 00945 fprintf_filtered (stream, " ("); 00946 type_print (exp->elts[elt].type, NULL, stream, 0); 00947 fprintf_filtered (stream, ")"); 00948 elt += 2; 00949 break; 00950 case OP_TYPEOF: 00951 case OP_DECLTYPE: 00952 fprintf_filtered (stream, "Typeof ("); 00953 elt = dump_subexp (exp, stream, elt); 00954 fprintf_filtered (stream, ")"); 00955 break; 00956 case OP_TYPEID: 00957 fprintf_filtered (stream, "typeid ("); 00958 elt = dump_subexp (exp, stream, elt); 00959 fprintf_filtered (stream, ")"); 00960 break; 00961 case STRUCTOP_STRUCT: 00962 case STRUCTOP_PTR: 00963 { 00964 char *elem_name; 00965 int len; 00966 00967 len = longest_to_int (exp->elts[elt].longconst); 00968 elem_name = &exp->elts[elt + 1].string; 00969 00970 fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name); 00971 elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1)); 00972 } 00973 break; 00974 case OP_SCOPE: 00975 { 00976 char *elem_name; 00977 int len; 00978 00979 fprintf_filtered (stream, "Type @"); 00980 gdb_print_host_address (exp->elts[elt].type, stream); 00981 fprintf_filtered (stream, " ("); 00982 type_print (exp->elts[elt].type, NULL, stream, 0); 00983 fprintf_filtered (stream, ") "); 00984 00985 len = longest_to_int (exp->elts[elt + 1].longconst); 00986 elem_name = &exp->elts[elt + 2].string; 00987 00988 fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name); 00989 elt += 4 + BYTES_TO_EXP_ELEM (len + 1); 00990 } 00991 break; 00992 case TYPE_INSTANCE: 00993 { 00994 LONGEST len; 00995 00996 len = exp->elts[elt++].longconst; 00997 fprintf_filtered (stream, "%s TypeInstance: ", plongest (len)); 00998 while (len-- > 0) 00999 { 01000 fprintf_filtered (stream, "Type @"); 01001 gdb_print_host_address (exp->elts[elt].type, stream); 01002 fprintf_filtered (stream, " ("); 01003 type_print (exp->elts[elt].type, NULL, stream, 0); 01004 fprintf_filtered (stream, ")"); 01005 elt++; 01006 if (len > 0) 01007 fputs_filtered (", ", stream); 01008 } 01009 /* Ending LEN and ending TYPE_INSTANCE. */ 01010 elt += 2; 01011 elt = dump_subexp (exp, stream, elt); 01012 } 01013 break; 01014 default: 01015 case OP_NULL: 01016 case MULTI_SUBSCRIPT: 01017 case OP_F77_UNDETERMINED_ARGLIST: 01018 case OP_COMPLEX: 01019 case OP_STRING: 01020 case OP_BOOL: 01021 case OP_M2_STRING: 01022 case OP_THIS: 01023 case OP_NAME: 01024 fprintf_filtered (stream, "Unknown format"); 01025 } 01026 01027 return elt; 01028 } 01029 01030 void 01031 dump_prefix_expression (struct expression *exp, struct ui_file *stream) 01032 { 01033 int elt; 01034 01035 fprintf_filtered (stream, "Dump of expression @ "); 01036 gdb_print_host_address (exp, stream); 01037 fputs_filtered (", after conversion to prefix form:\nExpression: `", stream); 01038 print_expression (exp, stream); 01039 fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n", 01040 exp->language_defn->la_name, exp->nelts, 01041 (long) sizeof (union exp_element)); 01042 fputs_filtered ("\n", stream); 01043 01044 for (elt = 0; elt < exp->nelts;) 01045 elt = dump_subexp (exp, stream, elt); 01046 fputs_filtered ("\n", stream); 01047 }