7b4ac7e1 |
1 | /* Evaluate expressions for GDB. |
4187119d |
2 | Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. |
7b4ac7e1 |
3 | |
4187119d |
4 | This file is part of GDB. |
7b4ac7e1 |
5 | |
4187119d |
6 | GDB is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 1, or (at your option) |
9 | any later version. |
7b4ac7e1 |
10 | |
4187119d |
11 | GDB is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GDB; see the file COPYING. If not, write to |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
7b4ac7e1 |
19 | |
20 | #include "defs.h" |
e91b87a3 |
21 | #include "param.h" |
7b4ac7e1 |
22 | #include "symtab.h" |
23 | #include "value.h" |
24 | #include "expression.h" |
25 | |
7b4ac7e1 |
26 | \f |
27 | /* Parse the string EXP as a C expression, evaluate it, |
28 | and return the result as a number. */ |
29 | |
30 | CORE_ADDR |
31 | parse_and_eval_address (exp) |
32 | char *exp; |
33 | { |
34 | struct expression *expr = parse_c_expression (exp); |
35 | register CORE_ADDR addr; |
36 | register struct cleanup *old_chain |
37 | = make_cleanup (free_current_contents, &expr); |
38 | |
e91b87a3 |
39 | addr = (CORE_ADDR) value_as_long (evaluate_expression (expr)); |
7b4ac7e1 |
40 | do_cleanups (old_chain); |
41 | return addr; |
42 | } |
43 | |
44 | /* Like parse_and_eval_address but takes a pointer to a char * variable |
45 | and advanced that variable across the characters parsed. */ |
46 | |
47 | CORE_ADDR |
48 | parse_and_eval_address_1 (expptr) |
49 | char **expptr; |
50 | { |
632ea0cc |
51 | struct expression *expr = parse_c_1 (expptr, 0, 0); |
7b4ac7e1 |
52 | register CORE_ADDR addr; |
53 | register struct cleanup *old_chain |
54 | = make_cleanup (free_current_contents, &expr); |
55 | |
56 | addr = value_as_long (evaluate_expression (expr)); |
57 | do_cleanups (old_chain); |
58 | return addr; |
59 | } |
60 | |
61 | value |
62 | parse_and_eval (exp) |
63 | char *exp; |
64 | { |
65 | struct expression *expr = parse_c_expression (exp); |
66 | register value val; |
67 | register struct cleanup *old_chain |
68 | = make_cleanup (free_current_contents, &expr); |
69 | |
70 | val = evaluate_expression (expr); |
71 | do_cleanups (old_chain); |
72 | return val; |
73 | } |
632ea0cc |
74 | |
75 | /* Parse up to a comma (or to a closeparen) |
76 | in the string EXPP as an expression, evaluate it, and return the value. |
77 | EXPP is advanced to point to the comma. */ |
78 | |
79 | value |
80 | parse_to_comma_and_eval (expp) |
81 | char **expp; |
82 | { |
83 | struct expression *expr = parse_c_1 (expp, 0, 1); |
84 | register value val; |
85 | register struct cleanup *old_chain |
86 | = make_cleanup (free_current_contents, &expr); |
87 | |
88 | val = evaluate_expression (expr); |
89 | do_cleanups (old_chain); |
90 | return val; |
91 | } |
7b4ac7e1 |
92 | \f |
93 | /* Evaluate an expression in internal prefix form |
94 | such as is constructed by expread.y. |
95 | |
96 | See expression.h for info on the format of an expression. */ |
97 | |
98 | static value evaluate_subexp (); |
99 | static value evaluate_subexp_for_address (); |
100 | static value evaluate_subexp_for_sizeof (); |
101 | static value evaluate_subexp_with_coercion (); |
102 | |
103 | /* Values of NOSIDE argument to eval_subexp. */ |
104 | enum noside |
e91b87a3 |
105 | { EVAL_NORMAL, |
106 | EVAL_SKIP, /* Only effect is to increment pos. */ |
107 | EVAL_AVOID_SIDE_EFFECTS, /* Don't modify any variables or |
4187119d |
108 | call any functions. The value |
109 | returned will have the correct |
110 | type, and will have an |
111 | approximately correct lvalue |
112 | type (inaccuracy: anything that is |
113 | listed as being in a register in |
114 | the function in which it was |
115 | declared will be lval_register). */ |
7b4ac7e1 |
116 | }; |
117 | |
118 | value |
119 | evaluate_expression (exp) |
120 | struct expression *exp; |
121 | { |
122 | int pc = 0; |
bb7592f0 |
123 | return evaluate_subexp (0, exp, &pc, EVAL_NORMAL); |
7b4ac7e1 |
124 | } |
125 | |
126 | /* Evaluate an expression, avoiding all memory references |
127 | and getting a value whose type alone is correct. */ |
128 | |
129 | value |
130 | evaluate_type (exp) |
131 | struct expression *exp; |
132 | { |
133 | int pc = 0; |
bb7592f0 |
134 | return evaluate_subexp (0, exp, &pc, EVAL_AVOID_SIDE_EFFECTS); |
7b4ac7e1 |
135 | } |
136 | |
137 | static value |
bb7592f0 |
138 | evaluate_subexp (expect_type, exp, pos, noside) |
139 | struct type *expect_type; |
7b4ac7e1 |
140 | register struct expression *exp; |
141 | register int *pos; |
142 | enum noside noside; |
143 | { |
144 | enum exp_opcode op; |
145 | int tem; |
e91b87a3 |
146 | register int pc, pc2, oldpos; |
bb7592f0 |
147 | register value arg1, arg2, arg3; |
7b4ac7e1 |
148 | int nargs; |
149 | value *argvec; |
150 | |
151 | pc = (*pos)++; |
152 | op = exp->elts[pc].opcode; |
153 | |
154 | switch (op) |
155 | { |
bb7592f0 |
156 | case OP_SCOPE: |
157 | tem = strlen (&exp->elts[pc + 2].string); |
4187119d |
158 | (*pos) += 3 + ((tem + sizeof (union exp_element)) |
159 | / sizeof (union exp_element)); |
bb7592f0 |
160 | return value_static_field (exp->elts[pc + 1].type, |
161 | &exp->elts[pc + 2].string, -1); |
162 | |
7b4ac7e1 |
163 | case OP_LONG: |
164 | (*pos) += 3; |
165 | return value_from_long (exp->elts[pc + 1].type, |
166 | exp->elts[pc + 2].longconst); |
167 | |
168 | case OP_DOUBLE: |
169 | (*pos) += 3; |
170 | return value_from_double (exp->elts[pc + 1].type, |
171 | exp->elts[pc + 2].doubleconst); |
172 | |
173 | case OP_VAR_VALUE: |
174 | (*pos) += 2; |
175 | if (noside == EVAL_SKIP) |
176 | goto nosideret; |
4187119d |
177 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
178 | { |
179 | struct symbol * sym = exp->elts[pc + 1].symbol; |
180 | enum lval_type lv; |
181 | |
182 | switch (SYMBOL_CLASS (sym)) |
183 | { |
184 | case LOC_CONST: |
185 | case LOC_LABEL: |
186 | case LOC_CONST_BYTES: |
187 | lv = not_lval; |
188 | case LOC_REGISTER: |
189 | case LOC_REGPARM: |
190 | lv = lval_register; |
191 | default: |
192 | lv = lval_memory; |
193 | } |
194 | |
195 | return value_zero (SYMBOL_TYPE (sym), lv); |
196 | } |
197 | else |
198 | return value_of_variable (exp->elts[pc + 1].symbol); |
7b4ac7e1 |
199 | |
200 | case OP_LAST: |
201 | (*pos) += 2; |
e91b87a3 |
202 | return access_value_history ((int) exp->elts[pc + 1].longconst); |
7b4ac7e1 |
203 | |
204 | case OP_REGISTER: |
205 | (*pos) += 2; |
e91b87a3 |
206 | return value_of_register ((int) exp->elts[pc + 1].longconst); |
7b4ac7e1 |
207 | |
208 | case OP_INTERNALVAR: |
209 | (*pos) += 2; |
210 | return value_of_internalvar (exp->elts[pc + 1].internalvar); |
211 | |
e91b87a3 |
212 | case OP_STRING: |
213 | tem = strlen (&exp->elts[pc + 1].string); |
4187119d |
214 | (*pos) += 2 + ((tem + sizeof (union exp_element)) |
215 | / sizeof (union exp_element)); |
e91b87a3 |
216 | if (noside == EVAL_SKIP) |
217 | goto nosideret; |
218 | return value_string (&exp->elts[pc + 1].string, tem); |
219 | |
220 | case TERNOP_COND: |
221 | /* Skip third and second args to evaluate the first one. */ |
222 | arg1 = evaluate_subexp (0, exp, pos, noside); |
223 | if (value_zerop (arg1)) |
224 | { |
225 | evaluate_subexp (0, exp, pos, EVAL_SKIP); |
226 | return evaluate_subexp (0, exp, pos, noside); |
227 | } |
228 | else |
229 | { |
230 | arg2 = evaluate_subexp (0, exp, pos, noside); |
231 | evaluate_subexp (0, exp, pos, EVAL_SKIP); |
232 | return arg2; |
233 | } |
234 | |
3bf57d21 |
235 | case OP_FUNCALL: |
236 | (*pos) += 2; |
bb7592f0 |
237 | op = exp->elts[*pos].opcode; |
238 | if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) |
239 | { |
240 | int fnptr; |
241 | int tem2; |
242 | |
e91b87a3 |
243 | nargs = (int) exp->elts[pc + 1].longconst + 1; |
bb7592f0 |
244 | /* First, evaluate the structure into arg2 */ |
245 | pc2 = (*pos)++; |
246 | |
247 | if (noside == EVAL_SKIP) |
248 | goto nosideret; |
249 | |
250 | if (op == STRUCTOP_MEMBER) |
251 | { |
252 | arg2 = evaluate_subexp_for_address (exp, pos, noside); |
253 | } |
254 | else |
255 | { |
256 | arg2 = evaluate_subexp (0, exp, pos, noside); |
257 | } |
258 | |
259 | /* If the function is a virtual function, then the |
260 | aggregate value (providing the structure) plays |
261 | its part by providing the vtable. Otherwise, |
262 | it is just along for the ride: call the function |
263 | directly. */ |
264 | |
265 | arg1 = evaluate_subexp (0, exp, pos, noside); |
266 | |
e91b87a3 |
267 | fnptr = (int) value_as_long (arg1); |
bb7592f0 |
268 | if (fnptr < 128) |
269 | { |
270 | struct type *basetype; |
271 | int i, j; |
272 | basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); |
273 | basetype = TYPE_VPTR_BASETYPE (basetype); |
274 | for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--) |
275 | { |
276 | struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i); |
277 | /* If one is virtual, then all are virtual. */ |
278 | if (TYPE_FN_FIELD_VIRTUAL_P (f, 0)) |
279 | for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j) |
280 | if (TYPE_FN_FIELD_VOFFSET (f, j) == fnptr) |
281 | { |
282 | value vtbl; |
283 | value base = value_ind (arg2); |
284 | struct type *fntype = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)); |
285 | |
286 | if (TYPE_VPTR_FIELDNO (basetype) < 0) |
287 | TYPE_VPTR_FIELDNO (basetype) |
288 | = fill_in_vptr_fieldno (basetype); |
289 | |
290 | VALUE_TYPE (base) = basetype; |
291 | vtbl = value_field (base, TYPE_VPTR_FIELDNO (basetype)); |
292 | VALUE_TYPE (vtbl) = lookup_pointer_type (fntype); |
293 | VALUE_TYPE (arg1) = builtin_type_int; |
294 | arg1 = value_subscript (vtbl, arg1); |
295 | VALUE_TYPE (arg1) = fntype; |
296 | goto got_it; |
297 | } |
298 | } |
299 | if (i < 0) |
300 | error ("virtual function at index %d not found", fnptr); |
301 | } |
302 | else |
303 | { |
304 | VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))); |
305 | } |
306 | got_it: |
307 | |
308 | /* Now, say which argument to start evaluating from */ |
309 | tem = 2; |
310 | } |
311 | else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) |
312 | { |
313 | /* Hair for method invocations */ |
314 | int tem2; |
315 | |
e91b87a3 |
316 | nargs = (int) exp->elts[pc + 1].longconst + 1; |
bb7592f0 |
317 | /* First, evaluate the structure into arg2 */ |
318 | pc2 = (*pos)++; |
319 | tem2 = strlen (&exp->elts[pc2 + 1].string); |
320 | *pos += 2 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element); |
321 | if (noside == EVAL_SKIP) |
322 | goto nosideret; |
323 | |
324 | if (op == STRUCTOP_STRUCT) |
325 | { |
326 | arg2 = evaluate_subexp_for_address (exp, pos, noside); |
327 | } |
328 | else |
329 | { |
330 | arg2 = evaluate_subexp (0, exp, pos, noside); |
331 | } |
332 | /* Now, say which argument to start evaluating from */ |
333 | tem = 2; |
334 | } |
335 | else |
336 | { |
e91b87a3 |
337 | nargs = (int) exp->elts[pc + 1].longconst; |
bb7592f0 |
338 | tem = 0; |
339 | } |
340 | argvec = (value *) alloca (sizeof (value) * (nargs + 2)); |
341 | for (; tem <= nargs; tem++) |
3bf57d21 |
342 | /* Ensure that array expressions are coerced into pointer objects. */ |
343 | argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); |
344 | |
bb7592f0 |
345 | /* signal end of arglist */ |
346 | argvec[tem] = 0; |
347 | |
348 | if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) |
349 | { |
4187119d |
350 | int static_memfuncp; |
351 | |
bb7592f0 |
352 | argvec[1] = arg2; |
353 | argvec[0] = |
354 | value_struct_elt (arg2, argvec+1, &exp->elts[pc2 + 1].string, |
4187119d |
355 | &static_memfuncp, |
bb7592f0 |
356 | op == STRUCTOP_STRUCT |
357 | ? "structure" : "structure pointer"); |
4187119d |
358 | if (static_memfuncp) |
359 | { |
360 | argvec[1] = argvec[0]; |
361 | nargs--; |
362 | argvec++; |
363 | } |
bb7592f0 |
364 | } |
365 | else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) |
366 | { |
367 | argvec[1] = arg2; |
368 | argvec[0] = arg1; |
369 | } |
370 | |
3bf57d21 |
371 | if (noside == EVAL_SKIP) |
372 | goto nosideret; |
373 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
e91b87a3 |
374 | { |
375 | /* If the return type doesn't look like a function type, call an |
376 | error. This can happen if somebody tries to turn a variable into |
377 | a function call. This is here because people often want to |
378 | call, eg, strcmp, which gdb doesn't know is a function. If |
379 | gdb isn't asked for it's opinion (ie. through "whatis"), |
380 | it won't offer it. */ |
3bf57d21 |
381 | |
e91b87a3 |
382 | struct type *ftype = |
383 | TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])); |
7b4ac7e1 |
384 | |
e91b87a3 |
385 | if (ftype) |
386 | return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]))); |
387 | else |
388 | error ("Expression of type other than \"Function returning ...\" used as function"); |
7b4ac7e1 |
389 | } |
e91b87a3 |
390 | return call_function (argvec[0], nargs, argvec + 1); |
7b4ac7e1 |
391 | |
392 | case STRUCTOP_STRUCT: |
393 | tem = strlen (&exp->elts[pc + 1].string); |
4187119d |
394 | (*pos) += 2 + ((tem + sizeof (union exp_element)) |
395 | / sizeof (union exp_element)); |
bb7592f0 |
396 | arg1 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
397 | if (noside == EVAL_SKIP) |
398 | goto nosideret; |
4187119d |
399 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
400 | return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1), |
401 | &exp->elts[pc + 1].string), |
402 | lval_memory); |
403 | else |
404 | return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string, 0, |
405 | "structure"); |
7b4ac7e1 |
406 | |
407 | case STRUCTOP_PTR: |
408 | tem = strlen (&exp->elts[pc + 1].string); |
409 | (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); |
bb7592f0 |
410 | arg1 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
411 | if (noside == EVAL_SKIP) |
412 | goto nosideret; |
4187119d |
413 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
414 | return value_zero (lookup_struct_elt_type (TYPE_TARGET_TYPE |
415 | (VALUE_TYPE (arg1)), |
416 | &exp->elts[pc + 1].string), |
417 | lval_memory); |
418 | else |
419 | return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string, 0, |
420 | "structure pointer"); |
7b4ac7e1 |
421 | |
bb7592f0 |
422 | case STRUCTOP_MEMBER: |
423 | arg1 = evaluate_subexp_for_address (exp, pos, noside); |
424 | arg2 = evaluate_subexp (0, exp, pos, noside); |
425 | if (noside == EVAL_SKIP) |
426 | goto nosideret; |
427 | /* Now, convert these values to an address. */ |
4187119d |
428 | if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR |
429 | || ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) |
430 | != TYPE_CODE_MEMBER) |
431 | && (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) |
432 | != TYPE_CODE_METHOD))) |
433 | error ("non-pointer-to-member value used in pointer-to-member construct"); |
bb7592f0 |
434 | arg3 = value_from_long (builtin_type_long, |
435 | value_as_long (arg1) + value_as_long (arg2)); |
4187119d |
436 | VALUE_TYPE (arg3) = |
437 | lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))); |
bb7592f0 |
438 | return value_ind (arg3); |
439 | |
440 | case STRUCTOP_MPTR: |
441 | arg1 = evaluate_subexp (0, exp, pos, noside); |
442 | arg2 = evaluate_subexp (0, exp, pos, noside); |
443 | if (noside == EVAL_SKIP) |
444 | goto nosideret; |
445 | /* Now, convert these values to an address. */ |
4187119d |
446 | if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR |
447 | || (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER |
448 | && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD)) |
449 | error ("non-pointer-to-member value used in pointer-to-member construct"); |
bb7592f0 |
450 | arg3 = value_from_long (builtin_type_long, |
451 | value_as_long (arg1) + value_as_long (arg2)); |
4187119d |
452 | VALUE_TYPE (arg3) = |
453 | lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))); |
bb7592f0 |
454 | return value_ind (arg3); |
455 | |
7b4ac7e1 |
456 | case BINOP_ASSIGN: |
bb7592f0 |
457 | arg1 = evaluate_subexp (0, exp, pos, noside); |
458 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
459 | if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) |
460 | return arg1; |
bb7592f0 |
461 | if (binop_user_defined_p (op, arg1, arg2)) |
462 | return value_x_binop (arg1, arg2, op, 0); |
463 | else |
464 | return value_assign (arg1, arg2); |
7b4ac7e1 |
465 | |
466 | case BINOP_ASSIGN_MODIFY: |
467 | (*pos) += 2; |
bb7592f0 |
468 | arg1 = evaluate_subexp (0, exp, pos, noside); |
469 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
470 | if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) |
471 | return arg1; |
472 | op = exp->elts[pc + 1].opcode; |
bb7592f0 |
473 | if (binop_user_defined_p (op, arg1, arg2)) |
474 | return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op); |
475 | else if (op == BINOP_ADD) |
7b4ac7e1 |
476 | arg2 = value_add (arg1, arg2); |
477 | else if (op == BINOP_SUB) |
478 | arg2 = value_sub (arg1, arg2); |
479 | else |
480 | arg2 = value_binop (arg1, arg2, op); |
481 | return value_assign (arg1, arg2); |
482 | |
483 | case BINOP_ADD: |
484 | arg1 = evaluate_subexp_with_coercion (exp, pos, noside); |
485 | arg2 = evaluate_subexp_with_coercion (exp, pos, noside); |
486 | if (noside == EVAL_SKIP) |
487 | goto nosideret; |
bb7592f0 |
488 | if (binop_user_defined_p (op, arg1, arg2)) |
489 | return value_x_binop (arg1, arg2, op, 0); |
490 | else |
491 | return value_add (arg1, arg2); |
7b4ac7e1 |
492 | |
493 | case BINOP_SUB: |
494 | arg1 = evaluate_subexp_with_coercion (exp, pos, noside); |
495 | arg2 = evaluate_subexp_with_coercion (exp, pos, noside); |
496 | if (noside == EVAL_SKIP) |
497 | goto nosideret; |
bb7592f0 |
498 | if (binop_user_defined_p (op, arg1, arg2)) |
499 | return value_x_binop (arg1, arg2, op, 0); |
500 | else |
501 | return value_sub (arg1, arg2); |
7b4ac7e1 |
502 | |
503 | case BINOP_MUL: |
504 | case BINOP_DIV: |
505 | case BINOP_REM: |
506 | case BINOP_LSH: |
507 | case BINOP_RSH: |
508 | case BINOP_LOGAND: |
509 | case BINOP_LOGIOR: |
510 | case BINOP_LOGXOR: |
bb7592f0 |
511 | arg1 = evaluate_subexp (0, exp, pos, noside); |
512 | arg2 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
513 | if (noside == EVAL_SKIP) |
514 | goto nosideret; |
bb7592f0 |
515 | if (binop_user_defined_p (op, arg1, arg2)) |
516 | return value_x_binop (arg1, arg2, op, 0); |
4187119d |
517 | else |
518 | if (noside == EVAL_AVOID_SIDE_EFFECTS |
519 | && op == BINOP_DIV) |
520 | return value_zero (VALUE_TYPE (arg1), not_lval); |
bb7592f0 |
521 | else |
522 | return value_binop (arg1, arg2, op); |
7b4ac7e1 |
523 | |
524 | case BINOP_SUBSCRIPT: |
525 | arg1 = evaluate_subexp_with_coercion (exp, pos, noside); |
526 | arg2 = evaluate_subexp_with_coercion (exp, pos, noside); |
527 | if (noside == EVAL_SKIP) |
528 | goto nosideret; |
4187119d |
529 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
530 | return value_zero (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), |
531 | VALUE_LVAL (arg1)); |
532 | |
bb7592f0 |
533 | if (binop_user_defined_p (op, arg1, arg2)) |
534 | return value_x_binop (arg1, arg2, op, 0); |
535 | else |
4187119d |
536 | return value_subscript (arg1, arg2); |
7b4ac7e1 |
537 | |
538 | case BINOP_AND: |
bb7592f0 |
539 | arg1 = evaluate_subexp (0, exp, pos, noside); |
e91b87a3 |
540 | if (noside == EVAL_SKIP) |
541 | { |
542 | arg2 = evaluate_subexp (0, exp, pos, noside); |
543 | goto nosideret; |
544 | } |
545 | |
546 | oldpos = *pos; |
547 | arg2 = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS); |
548 | *pos = oldpos; |
549 | |
bb7592f0 |
550 | if (binop_user_defined_p (op, arg1, arg2)) |
551 | { |
552 | arg2 = evaluate_subexp (0, exp, pos, noside); |
553 | return value_x_binop (arg1, arg2, op, 0); |
554 | } |
555 | else |
556 | { |
557 | tem = value_zerop (arg1); |
558 | arg2 = evaluate_subexp (0, exp, pos, |
559 | (tem ? EVAL_SKIP : noside)); |
560 | return value_from_long (builtin_type_int, |
e91b87a3 |
561 | (LONGEST) (!tem && !value_zerop (arg2))); |
bb7592f0 |
562 | } |
7b4ac7e1 |
563 | |
564 | case BINOP_OR: |
bb7592f0 |
565 | arg1 = evaluate_subexp (0, exp, pos, noside); |
e91b87a3 |
566 | if (noside == EVAL_SKIP) |
567 | { |
568 | arg2 = evaluate_subexp (0, exp, pos, noside); |
569 | goto nosideret; |
570 | } |
571 | |
572 | oldpos = *pos; |
573 | arg2 = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS); |
574 | *pos = oldpos; |
575 | |
bb7592f0 |
576 | if (binop_user_defined_p (op, arg1, arg2)) |
577 | { |
578 | arg2 = evaluate_subexp (0, exp, pos, noside); |
579 | return value_x_binop (arg1, arg2, op, 0); |
580 | } |
581 | else |
582 | { |
583 | tem = value_zerop (arg1); |
584 | arg2 = evaluate_subexp (0, exp, pos, |
585 | (!tem ? EVAL_SKIP : noside)); |
586 | return value_from_long (builtin_type_int, |
e91b87a3 |
587 | (LONGEST) (!tem || !value_zerop (arg2))); |
bb7592f0 |
588 | } |
7b4ac7e1 |
589 | |
590 | case BINOP_EQUAL: |
bb7592f0 |
591 | arg1 = evaluate_subexp (0, exp, pos, noside); |
592 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
593 | if (noside == EVAL_SKIP) |
594 | goto nosideret; |
bb7592f0 |
595 | if (binop_user_defined_p (op, arg1, arg2)) |
596 | { |
597 | return value_x_binop (arg1, arg2, op, 0); |
598 | } |
599 | else |
600 | { |
601 | tem = value_equal (arg1, arg2); |
e91b87a3 |
602 | return value_from_long (builtin_type_int, (LONGEST) tem); |
bb7592f0 |
603 | } |
7b4ac7e1 |
604 | |
605 | case BINOP_NOTEQUAL: |
bb7592f0 |
606 | arg1 = evaluate_subexp (0, exp, pos, noside); |
607 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
608 | if (noside == EVAL_SKIP) |
609 | goto nosideret; |
bb7592f0 |
610 | if (binop_user_defined_p (op, arg1, arg2)) |
611 | { |
612 | return value_x_binop (arg1, arg2, op, 0); |
613 | } |
614 | else |
615 | { |
616 | tem = value_equal (arg1, arg2); |
e91b87a3 |
617 | return value_from_long (builtin_type_int, (LONGEST) ! tem); |
bb7592f0 |
618 | } |
7b4ac7e1 |
619 | |
620 | case BINOP_LESS: |
bb7592f0 |
621 | arg1 = evaluate_subexp (0, exp, pos, noside); |
622 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
623 | if (noside == EVAL_SKIP) |
624 | goto nosideret; |
bb7592f0 |
625 | if (binop_user_defined_p (op, arg1, arg2)) |
626 | { |
627 | return value_x_binop (arg1, arg2, op, 0); |
628 | } |
629 | else |
630 | { |
631 | tem = value_less (arg1, arg2); |
e91b87a3 |
632 | return value_from_long (builtin_type_int, (LONGEST) tem); |
bb7592f0 |
633 | } |
7b4ac7e1 |
634 | |
635 | case BINOP_GTR: |
bb7592f0 |
636 | arg1 = evaluate_subexp (0, exp, pos, noside); |
637 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
638 | if (noside == EVAL_SKIP) |
639 | goto nosideret; |
bb7592f0 |
640 | if (binop_user_defined_p (op, arg1, arg2)) |
641 | { |
642 | return value_x_binop (arg1, arg2, op, 0); |
643 | } |
644 | else |
645 | { |
646 | tem = value_less (arg2, arg1); |
e91b87a3 |
647 | return value_from_long (builtin_type_int, (LONGEST) tem); |
bb7592f0 |
648 | } |
7b4ac7e1 |
649 | |
650 | case BINOP_GEQ: |
bb7592f0 |
651 | arg1 = evaluate_subexp (0, exp, pos, noside); |
652 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
653 | if (noside == EVAL_SKIP) |
654 | goto nosideret; |
bb7592f0 |
655 | if (binop_user_defined_p (op, arg1, arg2)) |
656 | { |
657 | return value_x_binop (arg1, arg2, op, 0); |
658 | } |
659 | else |
660 | { |
661 | tem = value_less (arg1, arg2); |
e91b87a3 |
662 | return value_from_long (builtin_type_int, (LONGEST) ! tem); |
bb7592f0 |
663 | } |
7b4ac7e1 |
664 | |
665 | case BINOP_LEQ: |
bb7592f0 |
666 | arg1 = evaluate_subexp (0, exp, pos, noside); |
667 | arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); |
7b4ac7e1 |
668 | if (noside == EVAL_SKIP) |
669 | goto nosideret; |
bb7592f0 |
670 | if (binop_user_defined_p (op, arg1, arg2)) |
671 | { |
672 | return value_x_binop (arg1, arg2, op, 0); |
673 | } |
674 | else |
675 | { |
676 | tem = value_less (arg2, arg1); |
e91b87a3 |
677 | return value_from_long (builtin_type_int, (LONGEST) ! tem); |
bb7592f0 |
678 | } |
7b4ac7e1 |
679 | |
680 | case BINOP_REPEAT: |
bb7592f0 |
681 | arg1 = evaluate_subexp (0, exp, pos, noside); |
682 | arg2 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
683 | if (noside == EVAL_SKIP) |
684 | goto nosideret; |
4187119d |
685 | if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT) |
686 | error ("Non-integral right operand for \"@\" operator."); |
687 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
688 | return allocate_repeat_value (VALUE_TYPE (arg1), |
689 | (int) value_as_long (arg2)); |
690 | else |
691 | return value_repeat (arg1, (int) value_as_long (arg2)); |
7b4ac7e1 |
692 | |
693 | case BINOP_COMMA: |
bb7592f0 |
694 | evaluate_subexp (0, exp, pos, noside); |
695 | return evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
696 | |
697 | case UNOP_NEG: |
bb7592f0 |
698 | arg1 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
699 | if (noside == EVAL_SKIP) |
700 | goto nosideret; |
bb7592f0 |
701 | if (unop_user_defined_p (op, arg1)) |
4187119d |
702 | return value_x_unop (arg1, op); |
bb7592f0 |
703 | else |
704 | return value_neg (arg1); |
7b4ac7e1 |
705 | |
706 | case UNOP_LOGNOT: |
bb7592f0 |
707 | arg1 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
708 | if (noside == EVAL_SKIP) |
709 | goto nosideret; |
bb7592f0 |
710 | if (unop_user_defined_p (op, arg1)) |
4187119d |
711 | return value_x_unop (arg1, op); |
bb7592f0 |
712 | else |
713 | return value_lognot (arg1); |
7b4ac7e1 |
714 | |
715 | case UNOP_ZEROP: |
bb7592f0 |
716 | arg1 = evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
717 | if (noside == EVAL_SKIP) |
718 | goto nosideret; |
bb7592f0 |
719 | if (unop_user_defined_p (op, arg1)) |
4187119d |
720 | return value_x_unop (arg1, op); |
bb7592f0 |
721 | else |
e91b87a3 |
722 | return value_from_long (builtin_type_int, |
723 | (LONGEST) value_zerop (arg1)); |
7b4ac7e1 |
724 | |
725 | case UNOP_IND: |
bb7592f0 |
726 | if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR) |
727 | expect_type = TYPE_TARGET_TYPE (expect_type); |
728 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
729 | if (noside == EVAL_SKIP) |
730 | goto nosideret; |
4187119d |
731 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
732 | { |
733 | if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR |
734 | || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF |
735 | /* In C you can dereference an array to get the 1st elt. */ |
736 | || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY |
737 | ) |
738 | return value_zero (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), |
739 | lval_memory); |
740 | else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) |
741 | /* GDB allows dereferencing an int. */ |
1c997a4a |
742 | return value_zero (builtin_type_int, lval_memory); |
4187119d |
743 | else |
744 | error ("Attempt to take contents of a non-pointer value."); |
745 | } |
7b4ac7e1 |
746 | return value_ind (arg1); |
747 | |
748 | case UNOP_ADDR: |
bb7592f0 |
749 | /* C++: check for and handle pointer to members. */ |
750 | |
751 | op = exp->elts[*pos].opcode; |
752 | |
7b4ac7e1 |
753 | if (noside == EVAL_SKIP) |
754 | { |
bb7592f0 |
755 | if (op == OP_SCOPE) |
756 | { |
757 | char *name = &exp->elts[pc+3].string; |
758 | int tem = strlen (name); |
759 | (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); |
760 | } |
761 | else |
762 | evaluate_subexp (expect_type, exp, pos, EVAL_SKIP); |
7b4ac7e1 |
763 | goto nosideret; |
764 | } |
bb7592f0 |
765 | |
766 | if (op == OP_SCOPE) |
767 | { |
768 | char *name = &exp->elts[pc+3].string; |
769 | int tem = strlen (name); |
770 | struct type *domain = exp->elts[pc+2].type; |
771 | (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); |
772 | arg1 = value_struct_elt_for_address (domain, expect_type, name); |
773 | if (arg1) |
774 | return arg1; |
775 | error ("no field `%s' in structure", name); |
776 | } |
777 | else |
778 | return evaluate_subexp_for_address (exp, pos, noside); |
7b4ac7e1 |
779 | |
780 | case UNOP_SIZEOF: |
781 | if (noside == EVAL_SKIP) |
782 | { |
bb7592f0 |
783 | evaluate_subexp (0, exp, pos, EVAL_SKIP); |
7b4ac7e1 |
784 | goto nosideret; |
785 | } |
786 | return evaluate_subexp_for_sizeof (exp, pos); |
787 | |
788 | case UNOP_CAST: |
789 | (*pos) += 2; |
bb7592f0 |
790 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
791 | if (noside == EVAL_SKIP) |
792 | goto nosideret; |
793 | return value_cast (exp->elts[pc + 1].type, arg1); |
794 | |
795 | case UNOP_MEMVAL: |
796 | (*pos) += 2; |
bb7592f0 |
797 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
798 | if (noside == EVAL_SKIP) |
799 | goto nosideret; |
4187119d |
800 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
801 | return value_zero (exp->elts[pc + 1].type, lval_memory); |
802 | else |
803 | return value_at (exp->elts[pc + 1].type, |
804 | (CORE_ADDR) value_as_long (arg1)); |
7b4ac7e1 |
805 | |
806 | case UNOP_PREINCREMENT: |
bb7592f0 |
807 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
808 | if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) |
809 | return arg1; |
bb7592f0 |
810 | else if (unop_user_defined_p (op, arg1)) |
811 | { |
4187119d |
812 | return value_x_unop (arg1, op); |
bb7592f0 |
813 | } |
814 | else |
815 | { |
e91b87a3 |
816 | arg2 = value_add (arg1, value_from_long (builtin_type_char, |
817 | (LONGEST) 1)); |
bb7592f0 |
818 | return value_assign (arg1, arg2); |
819 | } |
7b4ac7e1 |
820 | |
821 | case UNOP_PREDECREMENT: |
bb7592f0 |
822 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
823 | if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) |
824 | return arg1; |
bb7592f0 |
825 | else if (unop_user_defined_p (op, arg1)) |
826 | { |
4187119d |
827 | return value_x_unop (arg1, op); |
bb7592f0 |
828 | } |
829 | else |
830 | { |
e91b87a3 |
831 | arg2 = value_sub (arg1, value_from_long (builtin_type_char, |
832 | (LONGEST) 1)); |
bb7592f0 |
833 | return value_assign (arg1, arg2); |
834 | } |
7b4ac7e1 |
835 | |
836 | case UNOP_POSTINCREMENT: |
bb7592f0 |
837 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
838 | if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) |
839 | return arg1; |
bb7592f0 |
840 | else if (unop_user_defined_p (op, arg1)) |
841 | { |
4187119d |
842 | return value_x_unop (arg1, op); |
bb7592f0 |
843 | } |
844 | else |
845 | { |
e91b87a3 |
846 | arg2 = value_add (arg1, value_from_long (builtin_type_char, |
847 | (LONGEST) 1)); |
bb7592f0 |
848 | value_assign (arg1, arg2); |
849 | return arg1; |
850 | } |
7b4ac7e1 |
851 | |
852 | case UNOP_POSTDECREMENT: |
bb7592f0 |
853 | arg1 = evaluate_subexp (expect_type, exp, pos, noside); |
7b4ac7e1 |
854 | if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) |
855 | return arg1; |
bb7592f0 |
856 | else if (unop_user_defined_p (op, arg1)) |
857 | { |
4187119d |
858 | return value_x_unop (arg1, op); |
bb7592f0 |
859 | } |
860 | else |
861 | { |
e91b87a3 |
862 | arg2 = value_sub (arg1, value_from_long (builtin_type_char, |
863 | (LONGEST) 1)); |
bb7592f0 |
864 | value_assign (arg1, arg2); |
865 | return arg1; |
866 | } |
867 | |
868 | case OP_THIS: |
869 | (*pos) += 1; |
870 | return value_of_this (1); |
871 | |
872 | default: |
e91b87a3 |
873 | error ("internal error: I do not know how to evaluate what you gave me"); |
7b4ac7e1 |
874 | } |
875 | |
876 | nosideret: |
e91b87a3 |
877 | return value_from_long (builtin_type_long, (LONGEST) 1); |
7b4ac7e1 |
878 | } |
879 | \f |
880 | /* Evaluate a subexpression of EXP, at index *POS, |
881 | and return the address of that subexpression. |
882 | Advance *POS over the subexpression. |
883 | If the subexpression isn't an lvalue, get an error. |
884 | NOSIDE may be EVAL_AVOID_SIDE_EFFECTS; |
885 | then only the type of the result need be correct. */ |
886 | |
887 | static value |
888 | evaluate_subexp_for_address (exp, pos, noside) |
889 | register struct expression *exp; |
890 | register int *pos; |
891 | enum noside noside; |
892 | { |
893 | enum exp_opcode op; |
894 | register int pc; |
895 | |
896 | pc = (*pos); |
897 | op = exp->elts[pc].opcode; |
898 | |
899 | switch (op) |
900 | { |
901 | case UNOP_IND: |
902 | (*pos)++; |
bb7592f0 |
903 | return evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
904 | |
905 | case UNOP_MEMVAL: |
906 | (*pos) += 3; |
907 | return value_cast (lookup_pointer_type (exp->elts[pc + 1].type), |
bb7592f0 |
908 | evaluate_subexp (0, exp, pos, noside)); |
7b4ac7e1 |
909 | |
910 | case OP_VAR_VALUE: |
911 | (*pos) += 3; |
4187119d |
912 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
913 | { |
914 | struct type *type = |
915 | lookup_pointer_type (SYMBOL_TYPE (exp->elts[pc + 1].symbol)); |
916 | enum address_class sym_class = |
917 | SYMBOL_CLASS (exp->elts[pc + 1].symbol); |
918 | |
919 | if (sym_class == LOC_CONST |
920 | || sym_class == LOC_CONST_BYTES |
921 | || sym_class == LOC_REGISTER |
922 | || sym_class == LOC_REGPARM) |
923 | error ("Attempt to take address of register or constant."); |
924 | |
925 | return |
926 | value_zero (type, not_lval); |
927 | } |
928 | else |
929 | return locate_var_value (exp->elts[pc + 1].symbol, (CORE_ADDR) 0); |
7b4ac7e1 |
930 | |
931 | default: |
4187119d |
932 | if (noside == EVAL_AVOID_SIDE_EFFECTS) |
933 | { |
934 | value x = evaluate_subexp (0, exp, pos, noside); |
935 | if (VALUE_LVAL (x) == lval_memory) |
936 | return value_zero (TYPE_POINTER_TYPE (VALUE_TYPE (x)), |
937 | not_lval); |
938 | else |
939 | error ("Attempt to take address of non-lval"); |
940 | } |
bb7592f0 |
941 | return value_addr (evaluate_subexp (0, exp, pos, noside)); |
7b4ac7e1 |
942 | } |
943 | } |
944 | |
945 | /* Evaluate like `evaluate_subexp' except coercing arrays to pointers. |
946 | When used in contexts where arrays will be coerced anyway, |
947 | this is equivalent to `evaluate_subexp' |
948 | but much faster because it avoids actually fetching array contents. */ |
949 | |
950 | static value |
951 | evaluate_subexp_with_coercion (exp, pos, noside) |
952 | register struct expression *exp; |
953 | register int *pos; |
954 | enum noside noside; |
955 | { |
956 | register enum exp_opcode op; |
957 | register int pc; |
958 | register value val; |
959 | |
960 | pc = (*pos); |
961 | op = exp->elts[pc].opcode; |
962 | |
963 | switch (op) |
964 | { |
965 | case OP_VAR_VALUE: |
966 | if (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 1].symbol)) == TYPE_CODE_ARRAY) |
967 | { |
968 | (*pos) += 3; |
969 | val = locate_var_value (exp->elts[pc + 1].symbol, (CORE_ADDR) 0); |
970 | return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (exp->elts[pc + 1].symbol))), |
971 | val); |
972 | } |
973 | } |
974 | |
bb7592f0 |
975 | return evaluate_subexp (0, exp, pos, noside); |
7b4ac7e1 |
976 | } |
977 | |
978 | /* Evaluate a subexpression of EXP, at index *POS, |
979 | and return a value for the size of that subexpression. |
980 | Advance *POS over the subexpression. */ |
981 | |
982 | static value |
983 | evaluate_subexp_for_sizeof (exp, pos) |
984 | register struct expression *exp; |
985 | register int *pos; |
986 | { |
987 | enum exp_opcode op; |
988 | register int pc; |
989 | value val; |
990 | |
991 | pc = (*pos); |
992 | op = exp->elts[pc].opcode; |
993 | |
994 | switch (op) |
995 | { |
996 | /* This case is handled specially |
997 | so that we avoid creating a value for the result type. |
998 | If the result type is very big, it's desirable not to |
999 | create a value unnecessarily. */ |
1000 | case UNOP_IND: |
1001 | (*pos)++; |
bb7592f0 |
1002 | val = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS); |
e91b87a3 |
1003 | return value_from_long (builtin_type_int, (LONGEST) |
1004 | TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (val)))); |
7b4ac7e1 |
1005 | |
1006 | case UNOP_MEMVAL: |
1007 | (*pos) += 3; |
e91b87a3 |
1008 | return value_from_long (builtin_type_int, |
1009 | (LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type)); |
7b4ac7e1 |
1010 | |
1011 | case OP_VAR_VALUE: |
1012 | (*pos) += 3; |
1013 | return value_from_long (builtin_type_int, |
e91b87a3 |
1014 | (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol))); |
7b4ac7e1 |
1015 | |
1016 | default: |
bb7592f0 |
1017 | val = evaluate_subexp (0, exp, pos, EVAL_AVOID_SIDE_EFFECTS); |
7b4ac7e1 |
1018 | return value_from_long (builtin_type_int, |
e91b87a3 |
1019 | (LONGEST) TYPE_LENGTH (VALUE_TYPE (val))); |
7b4ac7e1 |
1020 | } |
1021 | } |