|
|
1.1 ! root 1: /* Evaluate expressions for GDB. ! 2: Copyright (C) 1986, 1987 Free Software Foundation, Inc. ! 3: ! 4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY ! 5: WARRANTY. No author or distributor accepts responsibility to anyone ! 6: for the consequences of using it or for whether it serves any ! 7: particular purpose or works at all, unless he says so in writing. ! 8: Refer to the GDB General Public License for full details. ! 9: ! 10: Everyone is granted permission to copy, modify and redistribute GDB, ! 11: but only under the conditions described in the GDB General Public ! 12: License. A copy of this license is supposed to have been given to you ! 13: along with GDB so you can know your rights and responsibilities. It ! 14: should be in a file named COPYING. Among other things, the copyright ! 15: notice and this notice must be preserved on all copies. ! 16: ! 17: In other words, go ahead and share GDB, but don't try to stop ! 18: anyone else from sharing it farther. Help stamp out software hoarding! ! 19: */ ! 20: ! 21: #include "defs.h" ! 22: #include "initialize.h" ! 23: #include "symtab.h" ! 24: #include "value.h" ! 25: #include "expression.h" ! 26: ! 27: START_FILE ! 28: ! 29: /* Parse the string EXP as a C expression, evaluate it, ! 30: and return the result as a number. */ ! 31: ! 32: CORE_ADDR ! 33: parse_and_eval_address (exp) ! 34: char *exp; ! 35: { ! 36: struct expression *expr = parse_c_expression (exp); ! 37: register CORE_ADDR addr; ! 38: register struct cleanup *old_chain ! 39: = make_cleanup (free_current_contents, &expr); ! 40: ! 41: addr = value_as_long (evaluate_expression (expr)); ! 42: do_cleanups (old_chain); ! 43: return addr; ! 44: } ! 45: ! 46: /* Like parse_and_eval_address but takes a pointer to a char * variable ! 47: and advanced that variable across the characters parsed. */ ! 48: ! 49: CORE_ADDR ! 50: parse_and_eval_address_1 (expptr) ! 51: char **expptr; ! 52: { ! 53: struct expression *expr = parse_c_1 (expptr, 0, 0); ! 54: register CORE_ADDR addr; ! 55: register struct cleanup *old_chain ! 56: = make_cleanup (free_current_contents, &expr); ! 57: ! 58: addr = value_as_long (evaluate_expression (expr)); ! 59: do_cleanups (old_chain); ! 60: return addr; ! 61: } ! 62: ! 63: value ! 64: parse_and_eval (exp) ! 65: char *exp; ! 66: { ! 67: struct expression *expr = parse_c_expression (exp); ! 68: register value val; ! 69: register struct cleanup *old_chain ! 70: = make_cleanup (free_current_contents, &expr); ! 71: ! 72: val = evaluate_expression (expr); ! 73: do_cleanups (old_chain); ! 74: return val; ! 75: } ! 76: ! 77: /* Parse up to a comma (or to a closeparen) ! 78: in the string EXPP as an expression, evaluate it, and return the value. ! 79: EXPP is advanced to point to the comma. */ ! 80: ! 81: value ! 82: parse_to_comma_and_eval (expp) ! 83: char **expp; ! 84: { ! 85: struct expression *expr = parse_c_1 (expp, 0, 1); ! 86: register value val; ! 87: register struct cleanup *old_chain ! 88: = make_cleanup (free_current_contents, &expr); ! 89: ! 90: val = evaluate_expression (expr); ! 91: do_cleanups (old_chain); ! 92: return val; ! 93: } ! 94: ! 95: /* Evaluate an expression in internal prefix form ! 96: such as is constructed by expread.y. ! 97: ! 98: See expression.h for info on the format of an expression. */ ! 99: ! 100: static value evaluate_subexp (); ! 101: static value evaluate_subexp_for_address (); ! 102: static value evaluate_subexp_for_sizeof (); ! 103: static value evaluate_subexp_with_coercion (); ! 104: ! 105: /* Values of NOSIDE argument to eval_subexp. */ ! 106: enum noside ! 107: { EVAL_NORMAL, ! 108: EVAL_SKIP, ! 109: EVAL_AVOID_SIDE_EFFECTS, ! 110: }; ! 111: ! 112: value ! 113: evaluate_expression (exp) ! 114: struct expression *exp; ! 115: { ! 116: int pc = 0; ! 117: return evaluate_subexp (exp, &pc, EVAL_NORMAL); ! 118: } ! 119: ! 120: /* Evaluate an expression, avoiding all memory references ! 121: and getting a value whose type alone is correct. */ ! 122: ! 123: value ! 124: evaluate_type (exp) ! 125: struct expression *exp; ! 126: { ! 127: int pc = 0; ! 128: return evaluate_subexp (exp, &pc, EVAL_AVOID_SIDE_EFFECTS); ! 129: } ! 130: ! 131: static value ! 132: evaluate_subexp (exp, pos, noside) ! 133: register struct expression *exp; ! 134: register int *pos; ! 135: enum noside noside; ! 136: { ! 137: enum exp_opcode op; ! 138: int tem; ! 139: register int pc; ! 140: register value arg1, arg2; ! 141: int nargs; ! 142: value *argvec; ! 143: ! 144: pc = (*pos)++; ! 145: op = exp->elts[pc].opcode; ! 146: ! 147: switch (op) ! 148: { ! 149: case OP_LONG: ! 150: (*pos) += 3; ! 151: return value_from_long (exp->elts[pc + 1].type, ! 152: exp->elts[pc + 2].longconst); ! 153: ! 154: case OP_DOUBLE: ! 155: (*pos) += 3; ! 156: return value_from_double (exp->elts[pc + 1].type, ! 157: exp->elts[pc + 2].doubleconst); ! 158: ! 159: case OP_VAR_VALUE: ! 160: (*pos) += 2; ! 161: if (noside == EVAL_SKIP) ! 162: goto nosideret; ! 163: return value_of_variable (exp->elts[pc + 1].symbol); ! 164: ! 165: case OP_LAST: ! 166: (*pos) += 2; ! 167: return access_value_history (exp->elts[pc + 1].longconst); ! 168: ! 169: case OP_REGISTER: ! 170: (*pos) += 2; ! 171: return value_of_register (exp->elts[pc + 1].longconst); ! 172: ! 173: case OP_INTERNALVAR: ! 174: (*pos) += 2; ! 175: return value_of_internalvar (exp->elts[pc + 1].internalvar); ! 176: ! 177: case OP_FUNCALL: ! 178: (*pos) += 2; ! 179: nargs = exp->elts[pc + 1].longconst; ! 180: argvec = (value *) alloca (sizeof (value) * (nargs + 1)); ! 181: for (tem = 0; tem <= nargs; tem++) ! 182: ! 183: /* Ensure that array expressions are coerced into pointer objects. */ ! 184: argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); ! 185: ! 186: if (noside == EVAL_SKIP) ! 187: goto nosideret; ! 188: if (noside == EVAL_AVOID_SIDE_EFFECTS) ! 189: return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]))); ! 190: return call_function (argvec[0], nargs, argvec + 1); ! 191: ! 192: case OP_STRING: ! 193: tem = strlen (&exp->elts[pc + 1].string); ! 194: (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); ! 195: if (noside == EVAL_SKIP) ! 196: goto nosideret; ! 197: return value_string (&exp->elts[pc + 1].string, tem); ! 198: ! 199: case TERNOP_COND: ! 200: /* Skip third and second args to evaluate the first one. */ ! 201: arg1 = evaluate_subexp (exp, pos, noside); ! 202: if (value_zerop (arg1)) ! 203: { ! 204: evaluate_subexp (exp, pos, EVAL_SKIP); ! 205: return evaluate_subexp (exp, pos, noside); ! 206: } ! 207: else ! 208: { ! 209: arg2 = evaluate_subexp (exp, pos, noside); ! 210: evaluate_subexp (exp, pos, EVAL_SKIP); ! 211: return arg2; ! 212: } ! 213: ! 214: case STRUCTOP_STRUCT: ! 215: tem = strlen (&exp->elts[pc + 1].string); ! 216: (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); ! 217: arg1 = evaluate_subexp (exp, pos, noside); ! 218: if (noside == EVAL_SKIP) ! 219: goto nosideret; ! 220: return value_struct_elt (arg1, &exp->elts[pc + 1].string, ! 221: "structure"); ! 222: ! 223: case STRUCTOP_PTR: ! 224: tem = strlen (&exp->elts[pc + 1].string); ! 225: (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); ! 226: arg1 = evaluate_subexp (exp, pos, noside); ! 227: if (noside == EVAL_SKIP) ! 228: goto nosideret; ! 229: return value_struct_elt (arg1, &exp->elts[pc + 1].string, ! 230: "structure pointer"); ! 231: ! 232: case BINOP_ASSIGN: ! 233: arg1 = evaluate_subexp (exp, pos, noside); ! 234: arg2 = evaluate_subexp (exp, pos, noside); ! 235: if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) ! 236: return arg1; ! 237: return value_assign (arg1, arg2); ! 238: ! 239: case BINOP_ASSIGN_MODIFY: ! 240: (*pos) += 2; ! 241: arg1 = evaluate_subexp (exp, pos, noside); ! 242: arg2 = evaluate_subexp (exp, pos, noside); ! 243: if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) ! 244: return arg1; ! 245: op = exp->elts[pc + 1].opcode; ! 246: if (op == BINOP_ADD) ! 247: arg2 = value_add (arg1, arg2); ! 248: else if (op == BINOP_SUB) ! 249: arg2 = value_sub (arg1, arg2); ! 250: else ! 251: arg2 = value_binop (arg1, arg2, op); ! 252: return value_assign (arg1, arg2); ! 253: ! 254: case BINOP_ADD: ! 255: arg1 = evaluate_subexp_with_coercion (exp, pos, noside); ! 256: arg2 = evaluate_subexp_with_coercion (exp, pos, noside); ! 257: if (noside == EVAL_SKIP) ! 258: goto nosideret; ! 259: return value_add (arg1, arg2); ! 260: ! 261: case BINOP_SUB: ! 262: arg1 = evaluate_subexp_with_coercion (exp, pos, noside); ! 263: arg2 = evaluate_subexp_with_coercion (exp, pos, noside); ! 264: if (noside == EVAL_SKIP) ! 265: goto nosideret; ! 266: return value_sub (arg1, arg2); ! 267: ! 268: case BINOP_MUL: ! 269: case BINOP_DIV: ! 270: case BINOP_REM: ! 271: case BINOP_LSH: ! 272: case BINOP_RSH: ! 273: case BINOP_LOGAND: ! 274: case BINOP_LOGIOR: ! 275: case BINOP_LOGXOR: ! 276: arg1 = evaluate_subexp (exp, pos, noside); ! 277: arg2 = evaluate_subexp (exp, pos, noside); ! 278: if (noside == EVAL_SKIP) ! 279: goto nosideret; ! 280: return value_binop (arg1, arg2, op); ! 281: ! 282: case BINOP_SUBSCRIPT: ! 283: arg1 = evaluate_subexp_with_coercion (exp, pos, noside); ! 284: arg2 = evaluate_subexp_with_coercion (exp, pos, noside); ! 285: if (noside == EVAL_SKIP) ! 286: goto nosideret; ! 287: return value_subscript (arg1, arg2, op); ! 288: ! 289: case BINOP_AND: ! 290: arg1 = evaluate_subexp (exp, pos, noside); ! 291: tem = value_zerop (arg1); ! 292: arg2 = evaluate_subexp (exp, pos, ! 293: (tem ? EVAL_SKIP : noside)); ! 294: return value_from_long (builtin_type_int, ! 295: !tem && !value_zerop (arg2)); ! 296: ! 297: case BINOP_OR: ! 298: arg1 = evaluate_subexp (exp, pos, noside); ! 299: tem = value_zerop (arg1); ! 300: arg2 = evaluate_subexp (exp, pos, ! 301: (!tem ? EVAL_SKIP : noside)); ! 302: return value_from_long (builtin_type_int, ! 303: !tem || !value_zerop (arg2)); ! 304: ! 305: case BINOP_EQUAL: ! 306: arg1 = evaluate_subexp (exp, pos, noside); ! 307: arg2 = evaluate_subexp (exp, pos, noside); ! 308: if (noside == EVAL_SKIP) ! 309: goto nosideret; ! 310: tem = value_equal (arg1, arg2); ! 311: return value_from_long (builtin_type_int, tem); ! 312: ! 313: case BINOP_NOTEQUAL: ! 314: arg1 = evaluate_subexp (exp, pos, noside); ! 315: arg2 = evaluate_subexp (exp, pos, noside); ! 316: if (noside == EVAL_SKIP) ! 317: goto nosideret; ! 318: tem = value_equal (arg1, arg2); ! 319: return value_from_long (builtin_type_int, ! tem); ! 320: ! 321: case BINOP_LESS: ! 322: arg1 = evaluate_subexp (exp, pos, noside); ! 323: arg2 = evaluate_subexp (exp, pos, noside); ! 324: if (noside == EVAL_SKIP) ! 325: goto nosideret; ! 326: tem = value_less (arg1, arg2); ! 327: return value_from_long (builtin_type_int, tem); ! 328: ! 329: case BINOP_GTR: ! 330: arg1 = evaluate_subexp (exp, pos, noside); ! 331: arg2 = evaluate_subexp (exp, pos, noside); ! 332: if (noside == EVAL_SKIP) ! 333: goto nosideret; ! 334: tem = value_less (arg2, arg1); ! 335: return value_from_long (builtin_type_int, tem); ! 336: ! 337: case BINOP_GEQ: ! 338: arg1 = evaluate_subexp (exp, pos, noside); ! 339: arg2 = evaluate_subexp (exp, pos, noside); ! 340: if (noside == EVAL_SKIP) ! 341: goto nosideret; ! 342: tem = value_less (arg1, arg2); ! 343: return value_from_long (builtin_type_int, ! tem); ! 344: ! 345: case BINOP_LEQ: ! 346: arg1 = evaluate_subexp (exp, pos, noside); ! 347: arg2 = evaluate_subexp (exp, pos, noside); ! 348: if (noside == EVAL_SKIP) ! 349: goto nosideret; ! 350: tem = value_less (arg2, arg1); ! 351: return value_from_long (builtin_type_int, ! tem); ! 352: ! 353: case BINOP_REPEAT: ! 354: arg1 = evaluate_subexp (exp, pos, noside); ! 355: arg2 = evaluate_subexp (exp, pos, noside); ! 356: if (noside == EVAL_SKIP) ! 357: goto nosideret; ! 358: return value_repeat (arg1, value_as_long (arg2)); ! 359: ! 360: case BINOP_COMMA: ! 361: evaluate_subexp (exp, pos, noside); ! 362: return evaluate_subexp (exp, pos, noside); ! 363: ! 364: case UNOP_NEG: ! 365: arg1 = evaluate_subexp (exp, pos, noside); ! 366: if (noside == EVAL_SKIP) ! 367: goto nosideret; ! 368: return value_neg (arg1); ! 369: ! 370: case UNOP_LOGNOT: ! 371: arg1 = evaluate_subexp (exp, pos, noside); ! 372: if (noside == EVAL_SKIP) ! 373: goto nosideret; ! 374: return value_lognot (arg1); ! 375: ! 376: case UNOP_ZEROP: ! 377: arg1 = evaluate_subexp (exp, pos, noside); ! 378: if (noside == EVAL_SKIP) ! 379: goto nosideret; ! 380: return value_from_long (builtin_type_int, value_zerop (arg1)); ! 381: ! 382: case UNOP_IND: ! 383: arg1 = evaluate_subexp (exp, pos, noside); ! 384: if (noside == EVAL_SKIP) ! 385: goto nosideret; ! 386: return value_ind (arg1); ! 387: ! 388: case UNOP_ADDR: ! 389: if (noside == EVAL_SKIP) ! 390: { ! 391: evaluate_subexp (exp, pos, EVAL_SKIP); ! 392: goto nosideret; ! 393: } ! 394: return evaluate_subexp_for_address (exp, pos, noside); ! 395: ! 396: case UNOP_SIZEOF: ! 397: if (noside == EVAL_SKIP) ! 398: { ! 399: evaluate_subexp (exp, pos, EVAL_SKIP); ! 400: goto nosideret; ! 401: } ! 402: return evaluate_subexp_for_sizeof (exp, pos); ! 403: ! 404: case UNOP_CAST: ! 405: (*pos) += 2; ! 406: arg1 = evaluate_subexp (exp, pos, noside); ! 407: if (noside == EVAL_SKIP) ! 408: goto nosideret; ! 409: return value_cast (exp->elts[pc + 1].type, arg1); ! 410: ! 411: case UNOP_MEMVAL: ! 412: (*pos) += 2; ! 413: arg1 = evaluate_subexp (exp, pos, noside); ! 414: if (noside == EVAL_SKIP) ! 415: goto nosideret; ! 416: return value_at (exp->elts[pc + 1].type, value_as_long (arg1)); ! 417: ! 418: case UNOP_PREINCREMENT: ! 419: arg1 = evaluate_subexp (exp, pos, noside); ! 420: arg2 = value_add (arg1, value_from_long (builtin_type_char, 1)); ! 421: if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) ! 422: return arg1; ! 423: return value_assign (arg1, arg2); ! 424: ! 425: case UNOP_PREDECREMENT: ! 426: arg1 = evaluate_subexp (exp, pos, noside); ! 427: arg2 = value_sub (arg1, value_from_long (builtin_type_char, 1)); ! 428: if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) ! 429: return arg1; ! 430: return value_assign (arg1, arg2); ! 431: ! 432: case UNOP_POSTINCREMENT: ! 433: arg1 = evaluate_subexp (exp, pos, noside); ! 434: arg2 = value_add (arg1, value_from_long (builtin_type_char, 1)); ! 435: if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) ! 436: return arg1; ! 437: value_assign (arg1, arg2); ! 438: return arg1; ! 439: ! 440: case UNOP_POSTDECREMENT: ! 441: arg1 = evaluate_subexp (exp, pos, noside); ! 442: arg2 = value_sub (arg1, value_from_long (builtin_type_char, 1)); ! 443: if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) ! 444: return arg1; ! 445: value_assign (arg1, arg2); ! 446: return arg1; ! 447: } ! 448: ! 449: nosideret: ! 450: return value_from_long (builtin_type_long, 1); ! 451: } ! 452: ! 453: /* Evaluate a subexpression of EXP, at index *POS, ! 454: and return the address of that subexpression. ! 455: Advance *POS over the subexpression. ! 456: If the subexpression isn't an lvalue, get an error. ! 457: NOSIDE may be EVAL_AVOID_SIDE_EFFECTS; ! 458: then only the type of the result need be correct. */ ! 459: ! 460: static value ! 461: evaluate_subexp_for_address (exp, pos, noside) ! 462: register struct expression *exp; ! 463: register int *pos; ! 464: enum noside noside; ! 465: { ! 466: enum exp_opcode op; ! 467: register int pc; ! 468: ! 469: pc = (*pos); ! 470: op = exp->elts[pc].opcode; ! 471: ! 472: switch (op) ! 473: { ! 474: case UNOP_IND: ! 475: (*pos)++; ! 476: return evaluate_subexp (exp, pos, noside); ! 477: ! 478: case UNOP_MEMVAL: ! 479: (*pos) += 3; ! 480: return value_cast (lookup_pointer_type (exp->elts[pc + 1].type), ! 481: evaluate_subexp (exp, pos, noside)); ! 482: ! 483: case OP_VAR_VALUE: ! 484: (*pos) += 3; ! 485: return locate_var_value (exp->elts[pc + 1].symbol, (CORE_ADDR) 0); ! 486: ! 487: default: ! 488: return value_addr (evaluate_subexp (exp, pos, noside)); ! 489: } ! 490: } ! 491: ! 492: /* Evaluate like `evaluate_subexp' except coercing arrays to pointers. ! 493: When used in contexts where arrays will be coerced anyway, ! 494: this is equivalent to `evaluate_subexp' ! 495: but much faster because it avoids actually fetching array contents. */ ! 496: ! 497: static value ! 498: evaluate_subexp_with_coercion (exp, pos, noside) ! 499: register struct expression *exp; ! 500: register int *pos; ! 501: enum noside noside; ! 502: { ! 503: register enum exp_opcode op; ! 504: register int pc; ! 505: register value val; ! 506: ! 507: pc = (*pos); ! 508: op = exp->elts[pc].opcode; ! 509: ! 510: switch (op) ! 511: { ! 512: case OP_VAR_VALUE: ! 513: if (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 1].symbol)) == TYPE_CODE_ARRAY) ! 514: { ! 515: (*pos) += 3; ! 516: val = locate_var_value (exp->elts[pc + 1].symbol, (CORE_ADDR) 0); ! 517: return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (exp->elts[pc + 1].symbol))), ! 518: val); ! 519: } ! 520: } ! 521: ! 522: return evaluate_subexp (exp, pos, noside); ! 523: } ! 524: ! 525: /* Evaluate a subexpression of EXP, at index *POS, ! 526: and return a value for the size of that subexpression. ! 527: Advance *POS over the subexpression. */ ! 528: ! 529: static value ! 530: evaluate_subexp_for_sizeof (exp, pos) ! 531: register struct expression *exp; ! 532: register int *pos; ! 533: { ! 534: enum exp_opcode op; ! 535: register int pc; ! 536: value val; ! 537: ! 538: pc = (*pos); ! 539: op = exp->elts[pc].opcode; ! 540: ! 541: switch (op) ! 542: { ! 543: /* This case is handled specially ! 544: so that we avoid creating a value for the result type. ! 545: If the result type is very big, it's desirable not to ! 546: create a value unnecessarily. */ ! 547: case UNOP_IND: ! 548: (*pos)++; ! 549: val = evaluate_subexp (exp, pos, EVAL_AVOID_SIDE_EFFECTS); ! 550: return value_from_long (builtin_type_int, ! 551: TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (val)))); ! 552: ! 553: case UNOP_MEMVAL: ! 554: (*pos) += 3; ! 555: return value_from_long (builtin_type_int, ! 556: TYPE_LENGTH (exp->elts[pc + 1].type)); ! 557: ! 558: case OP_VAR_VALUE: ! 559: (*pos) += 3; ! 560: return value_from_long (builtin_type_int, ! 561: TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol))); ! 562: ! 563: default: ! 564: val = evaluate_subexp (exp, pos, EVAL_AVOID_SIDE_EFFECTS); ! 565: return value_from_long (builtin_type_int, ! 566: TYPE_LENGTH (VALUE_TYPE (val))); ! 567: } ! 568: } ! 569: ! 570: static ! 571: initialize () ! 572: { } ! 573: ! 574: END_FILE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.